轻量级锁不可撤销或降级,仅能升级为重量级锁;竞争时先自旋(默认10次),失败则膨胀;释放时cas写回成功即自然释放,失败则立即升级;锁升级单向且不可逆。

轻量级锁本身没有“撤销”概念,它只会在竞争失败后升级,或在无竞争时自然释放;所谓“恢复”,实际是指锁状态退回到更轻量的形态——但Java中锁不可降级,因此轻量级锁一旦升级为重量级锁,就不会再变回轻量级或偏向锁。
轻量级锁如何应对竞争
当线程尝试获取已被其他线程持有的轻量级锁时,会进入自旋等待而非立即阻塞:
- 先通过CAS尝试将对象头中的Mark Word替换为指向自己栈帧中Lock Record的指针
- CAS失败说明锁正被占用,此时启动自旋:默认最多10次(由
-XX:PreBlockSpin控制),且受CPU核心数影响 - 自旋期间若持有线程已退出同步块、对象头恢复为无锁或轻量级锁记录被清除,当前线程可重试CAS成功,直接获得轻量级锁
自旋失败后必然升级为重量级锁
一旦自旋耗尽仍未获取到锁,且持有线程仍在运行(非终止态),JVM会触发锁膨胀(inflation):
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 将对象头标记为“待膨胀”,新建一个
ObjectMonitor对象 - 原持有线程继续执行,当前线程被挂起并加入
_EntryList(等待获取锁)或_WaitSet(如调用了wait()) - 膨胀只发生一次,之后所有对该对象的锁请求都直接走重量级锁路径
不存在“恢复为轻量级锁”的机制
重量级锁不会因竞争减少而自动降级,这是JVM的设计原则:
- 锁升级是单向的:无锁 → 偏向锁 → 轻量级锁 → 重量级锁
- 即使后续长期只有单一线程访问,对象头仍指向
ObjectMonitor,每次加锁都需进入操作系统互斥量(mutex)操作 - 所谓“恢复”,仅可能出现在锁完全释放后的下一次加锁——若此时无竞争且满足条件(如JDK版本支持、未禁用偏向锁),新锁获取可能从偏向锁开始,但这不是对旧锁的恢复,而是全新的一轮锁获取流程
轻量级锁的“释放”不等于“撤销”
解锁过程是原子操作,成功与否决定是否触发升级:
- 线程退出同步块时,用CAS将栈中Displaced Mark Word写回对象头
- CAS成功:说明无竞争,锁彻底释放,对象回到无锁或可偏向状态
- CAS失败:说明已有其他线程在争抢,此时直接膨胀为重量级锁,原轻量级锁生命周期终结
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










