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

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











