偏向锁撤销后先进入轻量级锁,而非直接升级为重量级锁;撤销需在安全点执行,完成后对象回归无锁状态,新线程通过cas将对象头更新为指向lock record的指针(标志位00),失败则自旋。

当第二个线程尝试获取已被偏向的锁时,偏向锁就会被撤销,进而升级为轻量级锁。这个过程不是代码控制的,而是 JVM 在运行时自动触发的,关键在于竞争的发生和对象头 Mark Word 的状态变更。
偏向锁撤销是升级的前提
偏向锁本身不支持多线程并发进入。一旦有除原偏向线程外的其他线程尝试进入 synchronized 块,JVM 就判定存在竞争,必须撤销当前偏向状态。撤销不是立刻完成的,它需要等待 JVM 进入全局安全点(Safe Point),此时所有 Java 线程暂停执行,确保对象没有正在被修改或处于临界区中。
撤销过程分三步
- 暂停所有线程,检查原偏向线程是否仍在同步块内
- 若已退出,直接清除对象头中的线程 ID 和偏向标志位;若仍在执行,则需等待其自然退出临界区
- 撤销完成后,对象回归“无锁”状态(Mark Word 低 2 位仍为 01,但偏向位为 0,线程 ID 清空)
轻量级锁随即介入
此时新线程发现对象已无偏向,便按轻量级锁流程执行:
- 在自己的栈帧中创建 Lock Record,拷贝当前对象头的 Mark Word(即 Displaced Mark Word)
- 使用 CAS 操作,尝试将对象头更新为指向该 Lock Record 的指针
- 若 CAS 成功,Mark Word 低 2 位变为 00,锁进入轻量级状态;若失败,则开始自旋重试
注意两个跳过场景
- 静态方法锁、类对象锁(如
MyClass.class)默认不启用偏向锁,直接走轻量级锁流程 - JVM 启动后约 4 秒才启用偏向锁(可通过
-XX:BiasedLockingStartupDelay=0关闭延迟),此前新建对象也不会进入偏向状态
整个转换严格单向,不可逆,且完全由 Mark Word 的比特位变化体现——开发者无需写特殊代码,只需理解竞争如何触发状态迁移。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











