当前位置: 首页 > news >正文

孤舟笔记 并发篇七 synchronized和Lock到底啥区别?面试为什么年年都问这道题

文章目录

    • 先说结论:核心区别一览
    • synchronized:自动挡,省心但死板
    • Lock:手动挡,灵活但要自己负责
    • Condition:Lock 的杀手锏
    • synchronized 的逆袭:JVM 层面优化
    • synchronized vs Lock 全景
    • 回答技巧与点评
        • 标准回答
        • 加分回答
        • 面试官点评

个人网站

学 Java 并发的时候,你一定见过这对"双胞胎"——synchronizedLock。都是加锁,都能保证线程安全,那为啥要搞两套?面试官还特别喜欢问"它们的区别",你随口说一个"Lock 更灵活",面试官追问"灵活在哪",你就卡壳了。

今天咱们就把 synchronized 和 Lock 放在一起掰开了比,让你面试时能说个清清楚楚。

先说结论:核心区别一览

||| 维度 | synchronized | Lock(ReentrantLock) |
|||------|------|------|
||| 层面 | JVM 关键字 | JDK API 接口 |
||| 加锁方式 | 隐式加锁,进出自动 | 显式加锁,手动 lock/unlock |
||| 可中断性 | 不可中断 | lockInterruptibly() 可中断 |
||| 超时获取 | 不支持 | tryLock(timeout) 支持 |
||| 公平性 | 非公平锁 | 可选公平/非公平 |
||| 条件变量 | 只有一个 wait/notify | 多个 Condition 精准唤醒 |
||| 锁状态 | 无法判断是否获取到锁 | tryLock() 可判断 |
||| 释放锁 | 异常时自动释放 | 必须在 finally 中手动释放 |

一句话记住:synchronized 是自动挡,Lock 是手动挡——自动挡省心,手动挡灵活。

synchronized:自动挡,省心但死板

synchronized用起来特别简单,加个关键字就完事:

synchronized(obj){// 进入自动加锁,退出自动释放 👈balance-=100;}

你不需要手动释放锁,哪怕代码抛异常,JVM 也会保证锁被释放。这就是"自动挡"的好处——省心

但省心的代价是不灵活。你想中途放弃等锁?不行。你想设个超时?不行。你想精准唤醒某个等待线程?只能notifyAll()一把梭,把所有等着的线程都叫醒。

生活类比:synchronized就像自动门,人到门前自动开,人走自动关,但你没法控制它什么时候开、开多久。

Lock:手动挡,灵活但要自己负责

ReentrantLockLock接口最常用的实现类,用法稍微麻烦一点:

Locklock=newReentrantLock();lock.lock();// 手动加锁 👈try{balance-=100;}finally{lock.unlock();// 必须手动释放 👈 忘了就死锁!}

重点:unlock()必须放在finally块里。忘了释放锁,别的线程就永远等下去了。这是"手动挡"的代价——你得自己负责

但换来的灵活性非常强大:

1. 超时获取锁——不死等

if(lock.tryLock(3,TimeUnit.SECONDS)){// 3秒拿不到就放弃 👈try{/* 业务 */}finally{lock.unlock();}}

2. 可中断——等锁的时候能被打断

lock.lockInterruptibly();// 等锁期间可以被 interrupt() 打断 👈

3. 公平锁——先来先得

LockfairLock=newReentrantLock(true);// true = 公平锁 👈

synchronized只能是非公平锁,后来的线程可能"插队"先拿到锁。

Condition:Lock 的杀手锏

如果说tryLock和公平锁只是"锦上添花",那Condition就是 Lock 相比 synchronized 的杀手锏。

synchronized只有一把wait/notify,唤醒线程时没法指定是谁。但Lock可以创建多个Condition,精准唤醒:

Locklock=newReentrantLock();ConditionnotFull=lock.newCondition();// 队列没满条件 👈ConditionnotEmpty=lock.newCondition();// 队列没空条件 👈// 生产者:队列满了等"没满",放入后通知"没空"notFull.await();notEmpty.signal();// 精准唤醒消费者 👈// 消费者:队列空了等"没空",取出后通知"没满"notEmpty.await();notFull.signal();// 精准唤醒生产者 👈

synchronizednotifyAll()是大喇叭广播,Conditionsignal()是定向通知。生产者-消费者模型中,这个精准度差别太大了。

synchronized 的逆袭:JVM 层面优化

别以为synchronized就一无是处。JDK 6 之后,JVM 对synchronized做了大量优化:

  • 偏向锁:只有一个线程访问时,连 CAS 都省了
  • 轻量级锁:短时间竞争用 CAS 自旋,不阻塞
  • 重量级锁:竞争激烈才膨胀为操作系统互斥量

这些优化都是 JVM 自动完成的,你代码不用改。所以在竞争不激烈的场景,synchronized的性能并不比Lock差。

synchronized vs Lock 全景

synchronized 与 Lock 对比 全景 核心差异 ├── synchronized ── JVM 关键字,隐式加锁释放 │ ├── 自动释放锁(异常安全) │ ├── 不可中断、不可超时 │ ├── 只能非公平锁 │ └── 单条件变量(wait/notify) └── Lock ── JDK API,显式加锁释放 ├── 必须手动释放(finally 中 unlock) ├── 可中断(lockInterruptibly) ├── 可超时(tryLock) ├── 可选公平/非公平 └── 多条件变量(Condition) 选择建议 ├── 简单场景 → synchronized(代码简洁,自动优化) ├── 需要超时/中断/公平 → ReentrantLock └── 需要精准唤醒 → Lock + Condition 口诀:sync 自动省心用,Lock 灵活手动控, 超时中断公平锁,Condition 精准唤。

回答技巧与点评

标准回答

synchronized 是 JVM 层面的关键字,自动加锁释放锁,不可中断、不可超时、只能非公平;Lock 是 JDK 层面的 API 接口,需手动加锁释放,支持可中断、超时获取、公平锁选择,以及多个 Condition 精准唤醒。简单场景优先用 synchronized,需要灵活控制时用 Lock。

加分回答
  1. 设计哲学:synchronized 体现了"约定优于配置"的思想,用最简单的语法完成最常见的场景;Lock 体现了"显式优于隐式",把控制权交给开发者,适合复杂并发场景
  2. 性能边界:JDK 6 之后 synchronized 有偏向锁、轻量级锁等优化,低竞争场景性能不输 Lock。但高竞争场景下,Lock 的tryLock能避免线程长时间阻塞,整体吞吐量更优
  3. 进阶应用ReentrantReadWriteLock是 Lock 的另一个重要实现,读写分离,适合读多写少场景。synchronized 没有读写分离的能力
面试官点评

这道题考的是你对两种锁机制的全面理解和场景选择能力。只说"synchronized 自动、Lock 手动"太浅了。能展开讲 Condition 的精准唤醒、JVM 锁优化、以及 tryLock 在死锁避免中的作用,才能拿高分。如果能顺带提到 ReadWriteLock,说明你的知识面足够宽。

原文阅读


内容有帮助?点赞、收藏、关注三连!评论区等你 💪

http://www.jsqmd.com/news/723279/

相关文章:

  • 急需采购不用到处找!外架钢网片厂家、外架钢板网厂家、爬架网厂家哪家好?顺强丝网现货充足可定制 - 栗子测评
  • SSDTTime终极指南:5分钟自动化搞定黑苹果DSDT配置难题
  • 别再只盯着ADF了!用Python的statsmodels做KPSS检验,区分‘水平’与‘趋势’平稳的保姆级指南
  • 收藏!小白程序员轻松入门大模型:Transformer架构详解与实战应用
  • 别再只会用Statement了!手把手教你用PreparedStatement防止SQL注入(附MySQL 8.0配置)
  • 别再只用MD5了!Python实战HMAC-SHA1签名API请求(附JWT原理对比)
  • 生成式AI时代,品牌如何突破信息检索困局?搜极星给出终极答案
  • 手把手教你用STM32CubeMX配置I2C驱动IST8310磁力计(附完整代码)
  • DERL框架:可微分进化强化学习的奖励函数自动优化
  • AI网站克隆模板:用LLM与无头浏览器智能解析网页结构与设计
  • OpCore Simplify完全手册:零基础轻松创建专业级OpenCore EFI配置
  • 中小企业做线上难?不知道深圳互联网公司哪家好,万创科技深圳短视频代运营、新媒体运营、视频推广、抖音推广专业团队,靠谱 - 栗子测评
  • 2026年小程序商城分销系统?
  • 2026年专业中央厨房设备厂家实力排行 四川精选 - 优质品牌商家
  • 保姆级教程:在PVE 8.1上搞定黑群晖DSM 7.2,从引导到硬盘直通一步到位
  • TI Sitara AM62处理器:低功耗AI与HMI解决方案解析
  • FUSE-Bike平台:自行车载多模态感知与VRU行为识别
  • DAQiFi Nyquist 1物联网数据采集系统解析与应用
  • 多家塑料包装厂家深度对比,PE塑料袋厂家推荐真实测评,朗越内膜袋批发定制、方底袋立体袋源头厂为你揭秘 - 栗子测评
  • 008 编码器原理与位置反馈
  • Clera 智能助手深度评测:从参数解析到实战边界
  • ARM虚拟化指令陷阱机制与HFGITR_EL2寄存器解析
  • 从AMBA到AXI:聊聊ARM片上总线演进史,以及为什么FPGA设计离不开它
  • 从手册到实战:手把手教你配置Cortex-M7的TCM和Cache,提升实时性能
  • 扩散语言模型:原理、优势与工程实践
  • 光储系统控制与光伏阵列故障检测【附代码】
  • 2026年小程序商城页面设计?
  • 数学建模小白必看:用Pandas一行代码搞定Pearson和Spearman,附热力图绘制完整代码
  • 2026年四川商用厨房设备供应商专业度全维度解析:酒店厨房设备,食堂厨房设备,不锈钢厨房橱柜,实力盘点! - 优质品牌商家
  • Semtech AirLink XR60:工业级5G路由器的核心技术解析