当前位置: 首页 > backend >正文

synchronized锁升级过程【AI笔记,仅供自己参考】

在 Java 中,synchronized 是一种内置的同步机制,用于保证多线程环境下代码的原子性、可见性和有序性。从 JDK 1.6 开始,为了减少锁带来的性能开销,Java 对 synchronized 做了大量优化,引入了 锁升级机制(Lock Escalation)


🔐 一、什么是锁升级?

锁升级是指 JVM 在运行时根据对象的使用情况,对对象的锁状态进行动态优化的过程。它不是“升级为更重的锁”,而是从轻量级锁逐步升级到重量级锁的过程,以在不同竞争程度下取得性能平衡。


🧱 二、锁的类型(对象头中的 Mark Word)

在 Java 中,每个对象都有一个对象头(Object Header),其中的 Mark Word 保存了对象的哈希码、GC 分代年龄、锁状态等信息。锁的升级就体现在 Mark Word 的变化上。

锁的状态分为以下几种:

锁状态描述
无锁状态(Unlocked)对象未被任何线程锁定
偏向锁(Biased Locking)只有一个线程访问同步块时使用
轻量级锁(Lightweight Locking)多个线程交替执行同步块,没有竞争
重量级锁(Inflated Lock)多个线程发生竞争,锁膨胀为 OS 层面的互斥量(Mutex)

🔁 三、锁升级流程(从无锁到重量级锁)

深色版本

无锁状态│▼
偏向锁(只有一个线程)│(有竞争)▼
轻量级锁(CAS 尝试加锁)│(竞争激烈)▼
重量级锁(阻塞线程)

1. 无锁状态

  • 初始状态,对象未被任何线程锁定。
  • Mark Word 中记录的是对象的 hash、GC 信息等。

2. 偏向锁(Biased Locking)

  • 当一个线程访问同步块并获取锁时,JVM 会将对象头中的 Mark Word 设置为该线程 ID。
  • 表示这个对象“偏向”这个线程。
  • 优点:避免了无竞争情况下的同步开销。
  • 缺点:当有其他线程尝试获取锁时,偏向锁会失效,需要撤销(Revoke)并升级为轻量级锁。

✅ 偏向锁默认是开启的(JDK 6~15),但可以通过 JVM 参数关闭:

-XX:-UseBiasedLocking

3. 轻量级锁(Lightweight Locking)

  • 多个线程交替执行同步块,没有实际竞争
  • 使用 CAS(Compare and Swap)操作尝试将对象头的 Mark Word 替换为指向线程栈中锁记录的指针。
  • 如果 CAS 成功,则获得锁;失败则说明有竞争,进入锁膨胀。

4. 重量级锁(Inflated Lock)

  • 多个线程发生竞争时,锁会膨胀为 OS 层面的互斥锁(Mutex)。
  • JVM 会把线程阻塞,并等待操作系统调度。
  • 性能开销最大,因为涉及到线程上下文切换和系统调用。

🧪 四、锁升级的触发条件

条件锁升级
第一次加锁无锁 → 偏向锁
有线程竞争(偏向锁)偏向锁 → 轻量级锁
CAS 失败(轻量级锁)轻量级锁 → 重量级锁

📈 五、锁升级的性能影响

锁类型性能开销适用场景
偏向锁✅ 最低单线程访问同步块
轻量级锁⚠️ 较低多线程交替访问
重量级锁❌ 最高多线程竞争激烈

🧪 六、代码示例演示锁升级过程

public class SynchronizedLockUpgrade {public static void main(String[] args) throws InterruptedException {Object obj = new Object();new Thread(() -> {synchronized (obj) {System.out.println("Thread 1: holding lock");printMarkWord(obj);}}, "Thread-1").start();Thread.sleep(1000); // 确保 Thread-1 执行完偏向锁new Thread(() -> {synchronized (obj) {System.out.println("Thread 2: trying to get lock");printMarkWord(obj);}}, "Thread-2").start();}// 通过 JVM 工具打印对象头(Mark Word)private static void printMarkWord(Object obj) {// 实际中使用 JOL(Java Object Layout)库查看对象头// 示例代码略}
}

⚠️ 说明:要查看对象头(Mark Word)的变化,可以使用 JOL(Java Object Layout) 工具。


🛠️ 七、优化建议

场景建议
无并发竞争启用偏向锁,减少同步开销
短期竞争使用轻量级锁
长期竞争使用重量级锁或 ReentrantLock
高并发场景考虑使用 ReentrantLock 或分段锁(如 ConcurrentHashMap
不需要同步避免使用 synchronized,使用 volatile 或原子类

📚 八、相关 JVM 参数(了解)

参数说明
-XX:+UseBiasedLocking启用偏向锁(默认开启)
-XX:BiasedLockingStartupDelay=0提前启用偏向锁
-XX:-UseBiasedLocking禁用偏向锁
-XX:+PrintCommandLineFlags查看当前 JVM 使用的参数

✅ 九、总结:synchronized 的锁升级过程

步骤锁类型触发条件
1无锁状态初始状态
2偏向锁第一次加锁(单线程)
3轻量级锁多线程交替访问(CAS)
4重量级锁线程竞争激烈(锁膨胀)

📌 十、延伸阅读

  • Java Object Layout (JOL)
  • 《深入理解 Java 虚拟机》——周志明(第3版)
  • JVM 源码分析:synchronizer.cpp 和 objectMonitor.cpp

http://www.xdnf.cn/news/15726.html

相关文章:

  • NIO网络通信基础
  • P1205 [USACO1.2] 方块转换 Transformations
  • 如何检查GitHub上可能潜在的信息泄漏
  • Vue3 Anime.js超级炫酷的网页动画库详解
  • NW983NW988美光固态闪存NW991NW992
  • 一个简单的带TTL的LRU的C++实现
  • 《通信原理》学习笔记——第四章
  • IDEA 中 Maven 配置:当前项目与新项目的统一设置方法
  • final 使用
  • oracle 11.2.0.4 RAC下执行root.sh脚本报错
  • leetcode2_135.分发糖果
  • ollma dify 搭建合同审查助手
  • 【Python】一些PEP提案(三):with 语句、yield from、虚拟环境
  • MySQL中的索引和事务
  • vue2 面试题及详细答案150道(81 - 90)
  • 解锁 Java 并发编程的奥秘:《Java 并发编程之美》中的技术亮点与难题攻克
  • FastAdmin后台登录地址变更原理与手动修改方法-后台入口机制原理解析-优雅草卓伊凡
  • 【计算机网络】MAC地址与IP地址:网络通信的双重身份标识
  • TCP通讯开发注意事项及常见问题解析
  • 接口测试的原则、用例与流程详解
  • 百度权重提升技巧分析:从底层逻辑到实战策略
  • 某邮生活旋转验证码识别
  • 函数返回值问题,以及返回值的使用问题(c/c++)
  • 4G模块 A7680发送中文短信到手机
  • 2-大语言模型—理论基础:详解Transformer架构的实现(2)
  • 雾化技术赋能 全鼎如何打造软磁材料护城河
  • 最小生成树算法详解
  • 基于单片机红外感应智能卫生间系统仿真论文
  • 开源Docmost知识库管理工具
  • Web开发 02