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

摘要

在 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 小时前
golang定时器
开发语言·后端·golang
pengzhuofan3 小时前
第10章 Maven
java·maven
用户21411832636023 小时前
手把手教你在魔搭跑通 DeepSeek-OCR!光学压缩 + MoE 解码,97% 精度还省 10-20 倍 token
后端
追逐时光者3 小时前
一个基于 .NET 开源、功能强大的分布式微服务开发框架
后端·.net
百锦再4 小时前
Vue Scoped样式混淆问题详解与解决方案
java·前端·javascript·数据库·vue.js·学习·.net
刘一说4 小时前
Spring Boot 启动慢?启动过程深度解析与优化策略
java·spring boot·后端
壹佰大多4 小时前
【spring如何扫描一个路径下被注解修饰的类】
java·后端·spring
百锦再4 小时前
对前后端分离与前后端不分离(通常指服务端渲染)的架构进行全方位的对比分析
java·开发语言·python·架构·eclipse·php·maven
间彧4 小时前
Java双亲委派模型的具体实现原理是什么?
后端
间彧4 小时前
Java类的加载过程
后端