synchronized锁升级是JVM根据线程竞争自动触发的单向不可逆过程:无锁→偏向锁→轻量级锁→重量级锁;偏向锁为单线程优化,轻量级锁通过自旋应对交替竞争,重量级锁在高并发时启用内核态阻塞。

synchronized 锁升级不是人为控制的流程,而是 JVM 根据运行时线程竞争情况自动触发的状态演进。整个过程单向不可逆:从无锁 → 偏向锁 → 轻量级锁 → 重量级锁,每一步升级都由具体条件驱动,核心目标是用最低开销满足当前并发需求。
偏向锁:单线程场景下的“免检通道”
对象刚创建时处于无锁状态,Mark Word 存储哈希码和分代年龄,锁标志位为 01,偏向锁标志为 0。当第一个线程首次进入 synchronized 块时,JVM 在全局安全点尝试将该线程 ID 写入 Mark Word,并把偏向锁标志设为 1(仍保持锁标志位 01),锁即进入偏向状态。
- 后续同一线程再次进入,只需比对 Mark Word 中的线程 ID,一致就直接执行,不走 CAS、不挂起、不切换态
- 一旦有第二个线程尝试获取该锁,JVM 必须撤销偏向锁——这会触发一次全局安全点暂停,检查原持有线程是否存活
- 若原线程仍在运行,对象头被重置为无锁状态,然后立即升级为轻量级锁;若已退出,则直接恢复为无锁状态
轻量级锁:多线程交替竞争时的“自旋通道”
偏向锁撤销后,或原本就禁用偏向锁(如 JDK15+ 默认关闭),线程会在自己的栈帧中创建一个 Lock Record,通过 CAS 尝试将 Mark Word 替换为指向该记录的指针,锁标志位变为 00。
- CAS 成功:加锁完成,线程进入同步块
- CAS 失败:说明已有其他线程在竞争,当前线程开始自旋(空转等待),默认最多尝试 10 次(JDK 后期支持自适应自旋)
- 自旋失败、持有锁时间过长、或同时有多个线程争抢,都会导致轻量级锁膨胀为重量级锁
重量级锁:高并发下的“内核级守门人”
当轻量级锁自旋耗尽仍无法获取锁,JVM 会将 Mark Word 更新为指向 C++ 实现的 ObjectMonitor 对象的指针,锁标志位设为 10,正式进入重量级锁状态。
立即学习“Java免费学习笔记(深入)”;
- 未获取锁的线程被挂起,进入 Monitor 的 EntryList 队列,状态变为 BLOCKED
- 线程从用户态陷入内核态,依赖操作系统互斥量(Mutex)调度,上下文切换开销显著增大
- 一旦升级为重量级锁,该对象后续所有锁操作都维持重量级,不再降级或退回轻量/偏向状态
锁升级本质是 Mark Word 内容的动态改写,所有状态都编码在对象头里。理解它不需要记住每一步代码,关键是抓住三个判断点:有没有第二个线程来抢、自旋有没有成功、系统是否决定让线程睡觉而不是空转。


















