JVM在轻量级锁自旋失败后自动将锁升级为重量级锁,通过修改对象头Mark Word指向Monitor并置标志位为10,使后续线程调用操作系统互斥量阻塞,且升级不可逆。

当多个线程同时争抢同一个 synchronized 锁,且轻量级锁的自旋策略失效时,JVM 会自动将锁升级为重量级锁。这个过程不需手动干预,完全由 JVM 运行时根据竞争强度动态决定。
轻量级锁自旋失败是关键触发点
轻量级锁阶段,线程不会立即挂起,而是通过“自旋”(空循环)尝试获取锁。JVM 默认最多自旋 10 次(JDK 1.7+ 支持适应性自旋,会参考历史成功概率动态调整)。一旦自旋耗尽仍无法获得锁,就满足升级条件:
- 当前持有轻量级锁的线程尚未释放锁
- 至少一个竞争线程已完成全部自旋且失败
- JVM 判定继续自旋收益低、开销高(比如 CPU 空转浪费严重)
升级动作发生在 monitorenter 指令执行过程中
每个 synchronized 块在字节码中对应 monitorenter 指令。当线程执行该指令发现锁处于轻量级状态但获取失败,且自旋已终止,JVM 就会:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 在对象头的 Mark Word 中写入指向 Monitor 对象的指针(62 位)
- 将锁标志位从 00(轻量级锁)改为 10(重量级锁)
- 把所有未获取到锁的等待线程,放入 Monitor 的 EntryList 阻塞队列
重量级锁依赖操作系统互斥量
Monitor 是 JVM 在 C++ 层实现的同步结构,内部封装了操作系统的互斥量(Mutex)和条件变量。一旦升级完成:
立即学习“Java免费学习笔记(深入)”;
- 后续线程再尝试进入 synchronized 块,会直接调用操作系统 API 进行阻塞(如 pthread_mutex_lock)
- 这涉及用户态 → 内核态切换,带来明显上下文切换开销
- 被阻塞线程不再消耗 CPU,而是交由操作系统调度器统一管理唤醒
升级不可逆,且影响全局锁行为
锁升级是单向过程:无锁 → 偏向锁 → 轻量级锁 → 重量级锁,之后不会再降级。这意味着:
- 哪怕后续竞争消失,该对象的锁状态仍保持重量级
- 所有对该对象的 synchronized 访问,此后都走 Monitor 阻塞路径
- 可通过 JOL 工具查看对象头 Mark Word 最后两位是否为 10 来确认

















