Java中synchronized锁升级由JVM自动完成,按无锁→偏向锁→轻量级锁→重量级锁顺序升级且不可降级;偏向锁优化单线程重复进入,轻量级锁通过自旋应对少量竞争,重量级锁依赖操作系统互斥量实现阻塞等待。

Java 中 synchronized 的锁升级不是由程序员手动控制的,而是 JVM 在运行时根据竞争情况自动优化的过程,目的是在低竞争场景下减少同步开销。整个过程从“无锁”状态开始,按需逐步升级:偏向锁 → 轻量级锁 → 重量级锁,但不会降级(一旦升级为重量级锁,就保持该状态)。
偏向锁:单线程重复进入的优化
当一个线程第一次获取锁时,JVM 会将对象头中的 Mark Word 设置为偏向模式,并记录该线程 ID。后续该线程再次进入同步块时,只需检查 Mark Word 中的线程 ID 是否匹配,无需 CAS 操作或挂起线程。
- 适用场景:大部分同步块由同一个线程反复进入(如 getter/setter、单线程初始化逻辑)
- 撤销条件:有其他线程尝试获取该锁;或到达全局安全点(safepoint)时发生批量撤销(如启动参数 -XX:-UseBiasedLocking 可禁用)
- 注意:偏向锁在 JDK 15+ 默认关闭,JDK 10 后已标记为 deprecated
轻量级锁:少量线程竞争时的自旋优化
当偏向锁被另一个线程竞争时,JVM 撤销偏向状态,升级为轻量级锁。此时线程会在用户态通过 CAS 尝试将对象头替换为指向栈中 Lock Record 的指针;失败则自旋重试(默认 10 次),不立即阻塞。
- 自旋成功:获得锁,继续执行
- 自旋失败:说明竞争加剧,升级为重量级锁
- 优点:避免频繁的内核态线程挂起/唤醒开销
- 缺点:CPU 空转,高竞争下反而浪费资源
重量级锁:真正依赖操作系统互斥量
当轻量级锁自旋失败,或已有线程在等待队列中,JVM 将锁膨胀为重量级锁。此时 Mark Word 指向 Monitor 对象(位于对象头或堆内存中),所有未获取锁的线程进入 Monitor 的 EntryList 阻塞等待,由操作系统调度唤醒。
立即学习“Java免费学习笔记(深入)”;
- Monitor 包含 Owner、EntryList、WaitSet 等字段,底层调用 pthread_mutex 或 Windows CriticalSection
- 一旦升级至此,后续所有同步操作都走重量级路径,不再尝试降级或回退
- 可通过 jstack 查看线程状态为 BLOCKED,对应 monitor 持有者
锁升级的触发与观察
锁升级是隐式发生的,无法直接编码控制,但可通过工具辅助分析:
- 开启 JVM 参数:-XX:+PrintGCDetails -XX:+UnlockDiagnosticVMOptions -XX:+PrintBiasedLockingStatistics 查看偏向锁统计
- 使用 JOL(Java Object Layout)查看对象头 Mark Word 变化(如 new Object() 初始为无锁,加 synchronized 后变化)
- 注意:锁升级发生在第一次加锁及后续竞争时刻,不是类加载或对象创建时


















