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

轻量级锁是什么?轻在哪里?重量级锁是什么?重在哪里?


轻量级锁 vs 重量级锁:核心区别与设计哲学

在JVM的锁优化体系中,轻量级锁和重量级锁是两种不同竞争强度下的解决方案。它们的核心差异体现在 资源消耗、适用场景和实现机制 上。以下是详细对比:


一、轻量级锁(Thin Lock)
1. 设计目标

优化场景:针对 低竞争短时间持有锁 的情况(如两个线程交替访问同步块)。
核心思想:通过 CAS自旋 避免线程直接阻塞,减少用户态到内核态的切换开销。

2. 实现原理

锁记录(Lock Record)
线程在栈帧中分配一个Lock Record空间,存储锁对象的Mark Word副本。
CAS竞争
通过CAS操作尝试将锁对象的Mark Word替换为指向Lock Record的指针。
成功:线程获取锁,Mark Word标志位变为轻量级锁(00)。
失败:触发 自旋等待锁膨胀(升级为重量级锁)。

3. "轻"在哪里?
维度轻量级锁原因
资源消耗仅需栈帧中的Lock Record和少量CAS操作不涉及内核态切换,无线程阻塞
性能开销纳秒级自旋(CPU空转)自旋时间短(JDK6后自适应调整),避免上下文切换
适用场景线程交替执行同步块(如短任务、低并发)竞争概率低,自旋成功率高
4. 示例流程
Object obj = new Object();
synchronized (obj) {  // 1. 栈帧创建Lock Record
                      // 2. CAS替换Mark Word
                      // 3. 成功则进入同步块
}

二、重量级锁(Heavyweight Lock)
1. 设计目标

处理高竞争:当多个线程激烈争抢同一锁时(如长时间持有锁或高并发场景)。
核心机制:通过操作系统提供的 互斥量(Mutex)条件变量 实现线程阻塞与唤醒。

2. 实现原理

Monitor对象
每个Java对象关联一个ObjectMonitor(C++实现),包含:
_owner:持有锁的线程
_EntryList:阻塞等待锁的线程队列
_WaitSet:调用wait()的线程队列
内核介入
线程竞争失败后,直接进入阻塞状态(通过pthread_mutex_lock),由操作系统调度唤醒。

3. "重"在哪里?
维度重量级锁原因
资源消耗需要维护ObjectMonitor和内核级线程调度涉及用户态→内核态切换,系统调用开销大
性能开销微秒级线程阻塞与唤醒线程阻塞导致上下文切换(CPU寄存器和堆栈保存/恢复)
适用场景长时间持有锁或高并发竞争(如数据库连接池)自旋代价过高,直接阻塞更高效
4. 示例流程
synchronized (highContentionLock) {  // 1. 竞争失败后加入_EntryList
                                     // 2. 线程被OS挂起
                                     // 3. 锁释放时唤醒等待线程
}

三、关键对比总结
特性轻量级锁重量级锁
锁标志位00(Mark Word中)10(Mark Word中)
竞争处理CAS自旋(用户态)线程阻塞(内核态)
资源占用栈帧中的Lock RecordObjectMonitor+内核队列
性能开销低(自旋消耗CPU周期)高(上下文切换、系统调用)
升级触发条件自旋失败或竞争激烈轻量级锁膨胀或显式调用wait()

四、锁升级的全流程
1. 无锁 → 偏向锁(单线程访问)
   └─ 出现第二个线程 → 撤销偏向锁
2. 轻量级锁(CAS自旋)
   └─ 自旋失败/长时间竞争 → 膨胀为重量级锁
3. 重量级锁(OS互斥量)

五、实际场景与调优建议
  1. 优先使用轻量级锁
    适用场景:短任务、低并发(如局部变量的同步块)。
    调优参数-XX:PreBlockSpin=10(调整自旋次数,JDK6后自适应无需手动设置)。

  2. 避免重量级锁的滥用
    问题:高竞争时频繁阻塞/唤醒会导致性能骤降。
    解决方案
    ◦ 减小锁粒度(如ConcurrentHashMap分段锁)。
    ◦ 改用无锁结构(如AtomicLong)。

  3. 监控锁状态
    工具
    ◦ JOL(Java Object Layout)查看对象头:
    java System.out.println(ClassLayout.parseInstance(obj).toPrintable());
    ◦ JConsole检查锁竞争:监控线程阻塞和等待时间。


总结

轻量级锁的"轻":体现在用户态自旋、低资源占用,适合短暂竞争。
重量级锁的"重":体现在内核态阻塞、高系统开销,应对高并发竞争。
设计哲学:JVM通过锁升级机制(偏向→轻量级→重量级)实现 按需分配资源,平衡性能与安全性。理解这一机制有助于编写高效并发代码,并在性能调优时精准定位锁瓶颈。

http://www.dtcms.com/a/123086.html

相关文章:

  • 技术与情感交织的一生 (五)
  • 无人机隐身技术难点要点!
  • [强网杯 2019]随便注 1
  • Matter的优势#4:安全性和加密
  • RHCSA Linux系统 数据流和重定向 tee 命令
  • 【非机动车检测】用YOLOv8实现非机动车及驾驶人佩戴安全帽检测
  • MySQL 的四种社交障碍等级
  • 经济金融最优化:从理论到MATLAB实践——最大利润问题全解析
  • 程序设计竞赛1
  • java笔记03
  • 安装了VM Tools,仍无法复制拖动-解决方案
  • 如何通过前端表格控件实现自动化报表?1
  • wsl2+ubuntu22.04安装blenderproc教程
  • React 的 context 是什么?
  • GPT - 因果掩码(Causal Mask)
  • C语言复习笔记--指针(4)
  • lombok的坑
  • JVM 调试与内存优化实战详解
  • 可编辑37页PPT | 建筑行业DeepSeek日常实操培训
  • keil5使用技巧
  • 踩雷,前端一直卡在获取token中
  • GaussDB存储过程深度解析:从开发到生产实践
  • 4.9-4.10学习总结 Stream流练习+方法引用+异常
  • C/C++内存管理:从基础到进阶
  • Leetcode 69——不使用sqrt函数情况下求平方根整数部分(暴力求解法和二分查找法)
  • Pytest多环境切换实战:测试框架配置的最佳实践!
  • EPGAN:融合高效注意力的生成对抗网络图像修复算法
  • Promise(微任务)和setTimeout(宏任务)的理解
  • P1825 [USACO11OPEN] Corn Maze S【java】【AC代码】
  • C++:函数模板类模板