偏向锁升级为轻量级锁需在安全点暂停线程,检查原偏向线程是否存活,撤销后对象回归无锁状态,新线程再以CAS+Lock Record方式获取轻量级锁;轻量级锁在CAS失败超阈值或自旋开销过大时,通过inflate()创建Monitor、更新Mark Word为10标识,升级为重量级锁。

锁升级是 JVM 运行时根据实际竞争情况自动完成的单向过程,不是由代码写法决定,而是由对象头(Mark Word)中锁标志位的动态变化体现。整个路径严格为:偏向锁 → 轻量级锁 → 重量级锁,不可逆,也没有“降级”可能。
偏向锁怎么变成轻量级锁?
当第二个线程尝试获取已被偏向的锁时,就触发偏向锁撤销,进而升级为轻量级锁。这个过程不是立刻发生的,它需要等待 JVM 进入全局安全点(Stop-The-World),然后执行以下步骤:
- 暂停所有 Java 线程,确保没有正在执行的临界区操作
- 检查原偏向线程是否仍持有该锁(是否还在同步块内)
- 若已退出,直接清除对象头中的线程 ID 和偏向标志;若仍在临界区内,则需等待其释放
- 撤销完成后,对象回到“无锁”状态,此时新线程会尝试用轻量级锁机制获取锁
注意:静态方法锁、类对象锁(如 MyClass.class)默认不启用偏向锁,因此跳过这一步,直接走轻量级锁流程。
轻量级锁怎么升级成重量级锁?
轻量级锁本质是“用户态自旋抢锁”,靠线程栈帧里的 Lock Record 和 CAS 操作实现。升级发生在竞争加剧时,具体条件包括:
- CAS 尝试获取锁失败次数达到阈值(默认 10 次,可通过 -XX:PreBlockSpin 调整)
- 自旋期间线程持续处于 RUNNABLE 状态,CPU 使用率升高但阻塞数极少
- 多个线程同时自旋导致 CAS 冲突率飙升,几乎必然超限升级
一旦判定升级,JVM 会将对象头的锁标志位改为 10,并关联一个 Monitor 对象,后续所有未获得锁的线程都会被挂起、进入操作系统等待队列。
对象头 Mark Word 是关键判断依据
所有锁状态切换都反映在对象头的 Mark Word 中。以 64 位虚拟机为例,其中 2 位用于表示锁状态:
- 01 + 偏向标志 = 偏向锁(含线程 ID)
- 00 = 轻量级锁(指向栈中 Lock Record 的指针)
- 10 = 重量级锁(指向 Monitor 的指针)
JVM 不依赖 synchronized 关键字本身做判断,而是在每次进入同步块前读取并修改 Mark Word,从而实现零感知的动态适配。

















