不一定,synchronized锁升级可跳过中间阶段:无锁可直接到轻量级锁(如禁用偏向锁)或重量级锁(如调用wait/notify),但一旦升级绝不降级,且偏向锁撤销后只能升为轻量级锁。

不一定。synchronized 锁升级不是必须依次经过所有四个阶段,而是根据实际运行时的线程竞争情况,跳过中间阶段、直接进入更高级别锁状态是完全可能的。
关键在于:JVM 会动态判断竞争强度,并选择最合适的起始锁策略,而不是机械地“一步步升”。
? 哪些阶段可以被跳过?
✅ 无锁 → 轻量级锁(跳过偏向锁)
-
触发条件:JVM 启动时通过
-XX:-UseBiasedLocking显式关闭偏向锁(JDK 15+ 默认禁用,JDK 17 LTS 也默认关闭); - 或对象所属类在初始化后的前 4 秒内未发生同步操作(JVM 的“偏向锁批量撤销窗口”已过);
- 或该对象已被多次用于高竞争场景(如被频繁作为锁对象且总有多个线程争抢)。
→ 此时,第一个线程进入 synchronized 块,不会尝试设置偏向锁,而是直接走轻量级锁流程:在栈中创建 Lock Record,用 CAS 替换 Mark Word。
✅ 无锁 → 重量级锁(极少但可能)
- 极端情况:某个对象被大量线程高频争抢,且 JVM 检测到该类型对象的历史锁行为几乎总是失败自旋;
- 或通过
-XX:BiasedLockingStartupDelay=0+ 立即触发多线程竞争,导致偏向锁快速撤销后又立刻因自旋失败而膨胀; - 更常见的是:代码中显式调用
Object.wait()/notify()—— 这会强制将锁升级为重量级锁(因为 Monitor 必须参与等待队列管理),哪怕此前还是偏向或轻量级状态。
→ 所以,只要涉及 wait/notify,锁必然落地到重量级状态,且不可逆。
❌ 哪些升级路径是严格固定的?
- 一旦升级,绝不降级:轻量级锁不会退回偏向锁,重量级锁也不会变回轻量级锁。
- 偏向锁撤销后,只能升级为轻量级锁(不是直接到重量级):撤销过程本身会把 Mark Word 恢复为无锁状态(标志位 01),然后下一个竞争线程按轻量级锁逻辑重新尝试 CAS。
- 轻量级锁自旋失败后,一定升级为重量级锁:这是唯一出口,没有“降级重试”机制。
? 实际例子说明
Object lock = new Object();
// 场景1:单线程反复执行(启用偏向锁)
for (int i = 0; i synchronized(lock) { /* ... */ });
Thread t2 = new Thread(() -> synchronized(lock) { /* ... */ });
t1.start(); t2.start(); // → 可能:无锁 → 偏向锁(t1)→ 撤销 → 轻量级锁(t2 自旋)→ 重量级锁(自旋失败)
// 场景3:JDK 17 默认关闭偏向锁,且立即多线程争抢
// → 直接:无锁 → 轻量级锁 → (自旋失败)→ 重量级锁
? 总结一句话
锁升级路径 无锁 → 偏向锁 → 轻量级锁 → 重量级锁 是理论上的完整链条和默认推荐路径,但 JVM 会依据配置、对象使用历史、是否调用 wait/notify 等因素,动态裁剪路径、跳过不适用阶段。真正驱动升级的,从来不是“顺序”,而是竞争事实和 JVM 的实时决策。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











