锁升级机制全解析:偏向锁、轻量级锁、重量级锁的秘密

摘要

在 HotSpot JVM 中,synchronized 并不是一开始就进入重量级锁。为了提升性能,JVM 设计了 锁升级机制:偏向锁 → 轻量级锁 → 重量级锁。本文将带你深入理解三种锁的特点、实现原理与适用场景,彻底搞清楚锁升级的秘密。


正文

一、为什么需要锁升级?

并发场景下,锁竞争频率差异巨大

  • 有时几乎无竞争;
  • 有时存在少量竞争;
  • 还有时竞争激烈。

如果一上来就使用重量级锁(基于操作系统的互斥量),会导致频繁 用户态 ↔ 内核态切换 ,性能开销大。

因此 JVM 引入了 分级锁机制,根据竞争情况逐步升级。


二、锁的三种形态

1. 偏向锁(Biased Lock)
  • 设计初衷 :优化 无竞争场景
  • 特点:锁会"偏向"第一个获取它的线程,如果后续没有其他线程竞争,该线程再次进入时无需加锁。
  • 实现方式 :在对象头的 Mark Word 中记录线程 ID,下次判断时只需比对线程 ID。
  • 适用场景:大量单线程操作的场景,比如对象被一个线程反复使用。
java 复制代码
synchronized(lock) {
    // 偏向锁:几乎零开销
}
2. 轻量级锁(Lightweight Lock)
  • 设计初衷 :优化 少量竞争场景
  • 特点 :多个线程尝试获取锁时,使用 CAS(Compare-And-Swap) 操作在用户态竞争,不涉及内核。
  • 实现方式 :JVM 会在当前线程栈中创建一个 锁记录(Lock Record) ,并尝试用 CAS 将对象头的 Mark Word 指向它。
  • 适用场景:锁竞争不激烈,但可能有多个线程交替进入的情况。
3. 重量级锁(Heavyweight Lock)
  • 设计初衷 :解决 激烈竞争场景
  • 特点:多个线程竞争失败后进入阻塞状态,由操作系统调度,唤醒时需要内核态切换,开销大。
  • 实现方式:Mark Word 指向 Monitor 对象,失败线程进入 Monitor 的 EntryList 队列等待。
  • 适用场景:高并发、竞争激烈,无法避免阻塞。

三、锁的升级过程

锁状态在 JVM 中的演进顺序如下:

无锁 → 偏向锁 → 轻量级锁 → 重量级锁

  • 偏向锁 → 轻量级锁:当另一个线程加入竞争时,偏向锁会撤销并升级为轻量级锁。
  • 轻量级锁 → 重量级锁:当 CAS 自旋失败或竞争严重时,锁升级为重量级锁,线程进入阻塞。

⚠️ 注意:锁只能升级,不能降级(除非对象被回收再分配)。


四、直观对比

锁类型 开销大小 是否阻塞 适用场景
偏向锁 最小 单线程反复使用对象
轻量级锁 中等 否(自旋) 少量竞争
重量级锁 最大 高并发激烈竞争

五、工程实践中的建议

  1. 减少锁的持有时间
    缩小同步代码块范围,避免长时间持锁。
  2. 避免不必要的共享
    如果数据能做到线程私有,就不需要锁。
  3. 热点资源分片
    将一个全局锁拆分为多把锁,降低竞争概率。
  4. 替代方案
  • 在竞争激烈场景,考虑使用 ReentrantLock,它支持公平锁、可中断、超时等特性;
  • 在读多写少场景,可以用 ReadWriteLockStampedLock 提升并发度。

六、总结

  • 偏向锁:几乎零开销,适合无竞争场景;
  • 轻量级锁:利用 CAS 自旋,适合少量竞争;
  • 重量级锁:基于操作系统互斥量,适合激烈竞争;
  • 锁升级:无锁 → 偏向 → 轻量级 → 重量级,不会降级。
相关推荐
金牌归来发现妻女流落街头3 分钟前
【从SpringBoot到SpringCloud】
java·spring boot·spring cloud
毅炼3 分钟前
Java 基础常见问题总结(4)
java·后端
GR23423415 分钟前
2025年影视仓TV+手机官方版 内置地址源支持高清直播
java·智能手机·软件
想用offer打牌25 分钟前
MCP (Model Context Protocol) 技术理解 - 第一篇
后端·aigc·mcp
千寻girling30 分钟前
Koa.js 教程 | 一份不可多得的 Node.js 的 Web 框架 Koa.js 教程
前端·后端·面试
程序员清风38 分钟前
北京回长沙了,简单谈谈感受!
java·后端·面试
何中应1 小时前
请求头设置没有生效
java·后端
NPE~1 小时前
自动化工具Drissonpage 保姆级教程(含xpath语法)
运维·后端·爬虫·自动化·网络爬虫·xpath·浏览器自动化
亓才孓1 小时前
[JDBC]批处理
java
春日见1 小时前
车辆动力学:前后轮车轴
java·开发语言·驱动开发·docker·计算机外设