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

摘要

在 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 自旋,适合少量竞争;
  • 重量级锁:基于操作系统互斥量,适合激烈竞争;
  • 锁升级:无锁 → 偏向 → 轻量级 → 重量级,不会降级。
相关推荐
菜鸟小九29 分钟前
SSM(MybatisPlus)
java·开发语言·spring boot·后端
不爱编程的小九九31 分钟前
小九源码-springboot051-智能推荐旅游平台
java·spring boot·后端
数据知道32 分钟前
Go基础:常用数学函数处理(主要是math包rand包的处理)
开发语言·后端·golang·go语言
期待のcode44 分钟前
MyBatis框架—延迟加载与多级缓存
java·数据库·后端·缓存·mybatis
老华带你飞1 小时前
小区服务|基于Java+vue的小区服务管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·小区服务管理系统
数据知道1 小时前
Go基础:文件与文件夹操作详解
开发语言·后端·golang·go语言
华仔啊1 小时前
Spring 配置混乱?搞懂这两个核心组件,问题真能少一半
java·后端·spring
喂完待续1 小时前
【序列晋升】45 Spring Data Elasticsearch 实战:3 个核心方案破解索引管理与复杂查询痛点,告别低效开发
java·后端·spring·big data·spring data·序列晋升
郑重其事,鹏程万里1 小时前
commons-exec
java
龙茶清欢1 小时前
具有实际开发参考意义的 MyBatis-Plus BaseEntity 基类示例
java·spring boot·spring cloud·mybatis