synchronized 锁升级流程
·
这张图片对
synchronized 锁升级流程的描述是 基本正确的,它准确抓住了 Java 6 之后为了减低性能损耗而设计的核心逻辑。
不过,作为一个技术控,为了让你在面试或实际开发中理解得更透彻,我们需要对图片中的描述进行一点点“精度校准”。
1. 锁升级的触发点(更精准的视角)
图片中提到的流程可以概括为:无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁。
- 偏向锁(Biased Locking):
- 核心逻辑:图片说得对,就是在对象头记录
threadID。只要还是同一个线程来,直接进,连 CAS 都不用做。 - 补充:偏向锁默认是有延迟开启的。另外,如果多个线程交替访问(没有竞争),偏向锁会被撤销并升级。
- 核心逻辑:图片说得对,就是在对象头记录
- 轻量级锁(Lightweight Locking):
- 触发条件:当有第二个线程尝试获取锁时,偏向锁升级。
- 实现方式:它通过 CAS 自旋来获取锁。这就是我们刚才讨论的“自适应自旋”发生的阶段。它不会阻塞线程,而是在用户态“死等”。
- 重量级锁(Heavyweight Locking):
- 触发条件:自旋超过一定次数,或者竞争过于激烈,锁就会膨胀。
- 实现方式:此时会使用操作系统底层的
Monitor,线程会被真正的阻塞(Park)。
2. 图片中一处需要微调的细节
图片里提到:“通过自旋循环一定次数来获取锁…如果还没有正常获取…就升级为重量级锁”。
- 微调建议:在现代 JVM 中,这个“一定次数”不再是死板的固定数字,而是我们刚才聊到的自适应自旋。JVM 会根据这个锁对象之前的表现来动态调整自旋时间。如果上次自旋 100 次成功了,这次可能允许它自旋 200 次;如果上次自旋失败了,这次可能直接跳过自旋,直接升级为重量级锁。
3. 为什么这个流程能提速?
图片总结得很到位:锁升级是为了减低性能消耗。
- 偏向锁:解决“单线程重复进出”的开销。
- 轻量级锁:解决“短时间内交替执行”的开销,避免线程在内核态反复横跳。
- 重量级锁:最后的防线,解决“长时间、高并发竞争”的问题,防止 CPU 被自旋线程跑满。
你的理解 Checkpoint
你之前问过“非公平锁排队”和“ConcurrentHashMap 选 synchronized”,现在结合这张图看,是不是闭环了?
- ConcurrentHashMap 选
synchronized,就是为了利用图里这种自动进化的能力。 - 在竞争不激烈时,它靠偏向锁/轻量级锁(CAS 自旋)快如闪电。
- 只有真正撞车严重时,它才会动用重量级锁去排队。
这份参考答案写得很精练,非常适合作为复习提纲。你对其中某个特定的锁状态(比如偏向锁撤销的代价)还有疑问吗?
更多推荐


所有评论(0)