synchronized锁升级是JVM自动触发的单向优化机制:无锁→偏向锁→轻量级锁→重量级锁;无锁为初始待机状态,偏向锁适用于单线程高频访问,轻量级锁应对低竞争交替,重量级锁处理高竞争并不可降级。

synchronized 锁升级不是程序员手动控制的流程,而是 JVM 在运行时根据线程竞争强度自动触发的优化机制。它本质是对象头(Mark Word)状态的渐进式变更,路径固定且单向:无锁 → 偏向锁 → 轻量级锁 → 重量级锁,每一步升级都只为在不同并发场景下平衡性能与正确性。
无锁是起点,不是“没锁”
对象刚创建时,Mark Word 中锁标志位为 01,偏向位为 0,此时不记录任何线程信息,也不含锁结构。它不代表“无需同步”,而是“尚未被锁定”的初始待机状态。一旦有线程首次进入 synchronized 块,JVM 就会尝试将其升级为偏向锁。
偏向锁面向单线程高频访问
适用于 getter/setter、单例初始化等几乎无竞争的场景:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 首次加锁时,JVM 用一次 CAS 将当前线程 ID 写入 Mark Word,锁标志位保持 01,但偏向位设为 1(即“01 + 偏向位=1”)
- 此后同一线程再次进入,只需比对 Mark Word 中的线程 ID,零同步开销
- 其他线程尝试获取该锁时,会触发偏向撤销——需等待全局安全点(safepoint),原线程若仍活跃则升级为轻量级锁;否则重置为无锁
- 注意:JDK 15+ 默认禁用,JDK 10 起已标记为 deprecated
轻量级锁应对低竞争交替场景
当偏向锁被撤销,或多个线程开始交替抢锁时启用:
立即学习“Java免费学习笔记(深入)”;
- 线程在自己栈帧中创建 Lock Record,尝试用 CAS 将 Mark Word 替换为指向该记录的指针,锁标志位变为 00
- CAS 成功 → 获得锁,直接执行;失败 → 进入自旋等待(默认最多 10 次)
- 自旋期间线程不挂起,避免用户态到内核态切换,节省上下文开销
- 自旋失败、或检测到多个线程同时等待,说明竞争加剧,就升级为重量级锁
重量级锁处理高竞争,靠操作系统保障
这是最终形态,不可降级,适用于多线程激烈争抢的场景:
- 对象头 Mark Word 存储指向堆中 Monitor 对象的指针,锁标志位变为 10
- 未获锁线程进入 Monitor 的 EntryList,并被操作系统挂起(BLOCKED 状态)
- 底层调用 pthread_mutex(Linux)或 CriticalSection(Windows),涉及内核态切换,开销显著
- 可通过 jstack 观察线程状态为 BLOCKED,对应持有 Monitor 的线程清晰可见

















