news 2026/5/1 8:44:04

孤舟笔记 并发篇八 可重入锁是什么?为什么面试官说没有它synchronized就是个残废

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
孤舟笔记 并发篇八 可重入锁是什么?为什么面试官说没有它synchronized就是个残废

文章目录

    • 先说结论:可重入锁的核心要点
    • 没有可重入锁会怎样?一个自我死锁的灾难
    • 可重入锁是怎么实现的?计数器 + 线程判断
    • synchronized 的可重入:JVM 层面天然支持
    • 可重入锁的注意事项
    • 可重入锁全景
    • 回答技巧与点评
        • 标准回答
        • 加分回答
        • 面试官点评

个人网站

你有没有写过这样的代码——方法 A 加了synchronized,方法 B 也加了synchronized,然后 A 调用了 B。按理说,A 已经拿到锁了,再去拿同一把锁,会不会把自己锁死?

如果锁不可重入,A 拿着锁等自己释放锁——这就是死锁。但神奇的是,程序跑得好好的,并没有卡住。这就是可重入锁在默默保护你。

先说结论:可重入锁的核心要点

维度说明
什么是可重入同一线程可以重复获取同一把锁,不会死锁
实现原理持锁线程 ID 判断 + 计数器(state)
每次加锁state +1
每次解锁state -1
完全释放state 减到 0 才真正释放锁
synchronized天然可重入(JVM 实现)
ReentrantLock可重入(AQS 的 state 计数)
不可重入的后果同一线程重入时自己锁死自己

一句话记住:可重入锁就像你家门锁——你在屋里,再推内门不用重新开锁;不可重入就是你把自己锁在卧室了。

没有可重入锁会怎样?一个自我死锁的灾难

假设锁不可重入,看这段代码:

publicsynchronizedvoidmethodA(){methodB();// A 已持有 this 锁,调用 B 还要拿 this 锁 👈}publicsynchronizedvoidmethodB(){// 如果锁不可重入,这里会永远等待 → 自己死锁!}

方法 A 拿到this对象的锁,调用方法 B,方法 B 也要拿this的锁。如果锁不可重入,线程 A 会等自己释放锁——左手等右手,永远等不到。

生活类比:你进了家门,卧室门也要用同一把钥匙。如果门锁"不可重入",你进了家门,再想进卧室——对不起,钥匙被你自己拿着呢,你得先"释放"家门锁才能开卧室门。但你人在家里,家门锁怎么释放?死锁了。

可重入锁就是解决这个问题:你已经拿过这把锁了,再拿一次直接放行,不用等。

可重入锁是怎么实现的?计数器 + 线程判断

可重入锁的核心就两步判断:

  1. 当前线程是不是已经持有这把锁?→ 是的话直接放行
  2. 计数器 +1,表示又重入了一次

ReentrantLock为例,它基于 AQS 实现:

// AQS 内部(简化)finalbooleannonfairTryAcquire(intacquires){intc=getState();// 获取当前 stateif(c==0){// 锁空闲,CAS 抢锁 👈if(compareAndSetState(0,acquires))setExclusiveOwnerThread(Thread.currentThread());}elseif(getExclusiveOwnerThread()==Thread.currentThread()){// 同一线程重入 👈 state 累加setState(c+acquires);returntrue;}returnfalse;}

关键逻辑:判断当前线程是否是持锁线程。如果是,state + 1,直接放行。

释放锁时反过来:

protectedfinalbooleantryRelease(intreleases){intc=getState()-releases;// state - 1 👈if(c==0){setExclusiveOwnerThread(null);// state 为 0 才真正释放 👈returntrue;}setState(c);returnfalse;}

state 减到 0 才真正释放锁。加了 3 次锁,就得解锁 3 次。

synchronized 的可重入:JVM 层面天然支持

synchronized的可重入不需要你操心,JVM 在底层就搞定了。每个对象头里有个 Monitor,内部有计数器_count,逻辑和ReentrantLock一模一样:

  • 同一线程再进synchronized→ 计数器 +1
  • 退出synchronized→ 计数器 -1
  • 计数器归零 → 释放 Monitor

所以你写synchronized嵌套调用,从来不用担心自己死锁自己——JVM 帮你兜底

可重入锁的注意事项

可重入锁虽然好用,但有几个坑:

1. 加几次锁,就得解几次锁

lock.lock();lock.lock();// state = 2lock.unlock();// state = 1,锁还没释放!👈// 必须再 unlock() 一次,state 才归零lock.unlock();// state = 0,锁真正释放

2. 子类重入父类的 synchronized 方法

classParent{publicsynchronizedvoiddoSomething(){/* ... */}}classChildextendsParent{@OverridepublicsynchronizedvoiddoSomething(){super.doSomething();// 重入同一把锁(this)👈}}

子类调用super.doSomething()是重入,不会死锁。但如果子类和父类用不同的锁对象,那就不是重入了。

可重入锁全景

可重入锁 全景 核心机制 ├── 线程判断 ── 当前线程 == 持锁线程 → 放行 ├── 计数器 ── state 记录重入次数 │ ├── 加锁 state +1 │ └── 解锁 state -1,归零才释放 └── 两个实现 ├── synchronized ── JVM Monitor 计数,天然可重入 └── ReentrantLock ── AQS state 计数,显式可重入 注意事项 ├── 加几次锁,解几次锁 ├── 子类调父类 synchronized 是重入 └── 不同锁对象不算重入 口诀:同线程可重入,计数器来帮忙, 加几次解几次,归零才是释放。

回答技巧与点评

标准回答

可重入锁是指同一线程可以重复获取同一把锁而不会死锁。实现原理是通过线程 ID 判断和计数器:持锁线程再次获取锁时,计数器加 1 而非阻塞;释放锁时计数器减 1,减到 0 才真正释放。synchronized 天然可重入(JVM Monitor 计数),ReentrantLock 也支持可重入(AQS 的 state 计数)。可重入锁的作用是避免同一线程在嵌套调用时自我死锁。

加分回答
  1. 设计原则:可重入锁体现了"最小意外"原则——如果同一线程已经持有锁,再次获取应该是自然行为而非死锁。几乎所有主流锁实现都支持可重入,不可重入锁属于特殊场景
  2. 边界情况ReentrantLocklock()unlock()必须成对出现,嵌套几次就 unlock 几次。如果只 unlock 一次,锁不会释放,其他线程永远等待——这是synchronized不会出的问题
  3. 实际应用:框架中大量使用可重入特性。比如 Spring 的事务管理器在@Transactional嵌套调用时,同一线程可以重复获取数据库连接锁;AQS 的acquire()方法本身也是可重入设计
面试官点评

这道题考的是你对锁机制的底层理解。只说"可重入就是能重复加锁"太浅了。能讲清楚 state 计数器的实现、为什么必须减到零才释放、以及 synchronized 和 ReentrantLock 在可重入上的不同实现路径,才能拿高分。如果你能指出"可重入是锁的基本能力,不是高级特性",面试官会认为你理解到位。

原文阅读


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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 8:43:16

揭秘番茄小说下载器:5个让你效率翻倍的架构设计创新

揭秘番茄小说下载器:5个让你效率翻倍的架构设计创新 【免费下载链接】Tomato-Novel-Downloader 番茄小说下载器不精简版 项目地址: https://gitcode.com/gh_mirrors/to/Tomato-Novel-Downloader 在数字阅读时代,如何高效地将在线内容转换为本地资…

作者头像 李华
网站建设 2026/5/1 8:41:34

EgoAVU多模态融合技术在动作识别中的应用与优化

1. 项目背景与核心价值 去年在CVPR会议上第一次看到EgoAVU这个项目时,我就被它独特的视角吸引了。作为长期从事多模态研究的工程师,我深知自我中心视角(Egocentric View)的数据处理有多棘手——这类数据往往包含大量运动模糊、剧烈…

作者头像 李华
网站建设 2026/5/1 8:39:44

3分钟上手:本地化视频字幕提取的完整解决方案

3分钟上手:本地化视频字幕提取的完整解决方案 【免费下载链接】video-subtitle-extractor 视频硬字幕提取,生成srt文件。无需申请第三方API,本地实现文本识别。基于深度学习的视频字幕提取框架,包含字幕区域检测、字幕内容提取。A…

作者头像 李华
网站建设 2026/5/1 8:37:22

大语言模型记忆机制与伦理风险解析

1. 项目背景与核心议题 上周调试大语言模型时,一个诡异现象让我停下了手中的咖啡:当要求模型"忘记"某个敏感话题后,它在后续对话中依然会通过隐喻方式重现相关内容。这引发了我对当前LLM记忆机制的深度思考——我们正在赋予AI越来越…

作者头像 李华
网站建设 2026/5/1 8:34:31

Codex 使用技巧(免费使用方法)

Codex 使用技巧(免费使用方法) Codex免费使用方法 Codex 更适合当作“编程副驾驶”,而不是完全自动开发工具。想用得稳定,核心原则是:任务要小、边界要清楚、结果要可验证。 1. 先分析,再修改 不要一上来…

作者头像 李华