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

synchronized锁升级的过程(从无锁到偏向锁,再到轻量级锁,最后到重量级锁的一个过程)

锁升级是 Java 中 synchronized 锁 的核心优化机制(基于 JVM 的 对象头 Mark Word 实现),指锁的状态从 无锁 → 偏向锁 → 轻量级锁 → 重量级锁 逐步升级的过程。其目的是通过 “按需升级”,在不同并发场景下选择最优的锁实现,平衡性能与线程安全。

一、锁的四种状态

在讲解升级过程前,需先明确 synchronized 锁的四种状态(按开销从小到大排序):

锁状态核心特点适用场景
无锁无锁竞争,对象未被任何线程锁定单线程访问
偏向锁仅记录第一个获取锁的线程 ID,后续该线程可直接重入,无需竞争单线程重复获取锁(无并发)
轻量级锁多线程交替获取锁,通过 CAS 操作 竞争锁,避免内核态切换低并发(线程交替执行)
重量级锁多线程同时竞争锁,依赖操作系统 互斥量(Mutex),会阻塞线程高并发(线程频繁竞争)

二、锁升级的完整过程

锁升级的触发条件是 “并发竞争加剧”,JVM 会根据线程竞争情况,自动将锁从低开销状态升级到高开销状态,且升级过程是 单向的(不可逆)(如偏向锁升级为轻量级锁后,不会再降级为偏向锁)。

1. 第一步:无锁 → 偏向锁

  • 触发场景:单线程首次获取 synchronized 锁时,JVM 为了减少锁开销,会将锁初始化为 “偏向锁”。
  • 核心操作
    1. 线程 A 尝试获取锁时,检查对象头的 Mark Word(存储对象锁状态的字段),发现当前是 “无锁” 状态。
    2. 通过 CAS 操作,将 Mark Word 中的 “锁状态” 改为 “偏向锁”,并记录线程 A 的 ID(threadId)和 “偏向时间戳”。
    3. 后续线程 A 再次进入 synchronized 代码块时,只需对比 Mark Word 中的线程 ID 是否为自己:
      • 是:直接重入锁,无需任何 CAS 或阻塞操作(开销极低)。
      • 否:触发偏向锁撤销,进入下一步升级。

2. 第二步:偏向锁 → 轻量级锁

  • 触发场景:当有 第二个线程(线程 B)尝试获取同一把锁 时,偏向锁的 “单线程假设” 被打破,JVM 会撤销偏向锁,升级为 “轻量级锁”。
  • 核心操作
    1. 线程 B 尝试获取锁时,发现 Mark Word 记录的是线程 A 的 ID(偏向锁状态),且线程 A 可能仍在执行(或已退出但未清理偏向锁)。
    2. JVM 首先会 暂停线程 A,检查线程 A 的状态:
      • 若线程 A 已退出:将 Mark Word 重置为 “无锁”,线程 B 重新尝试 CAS 获取轻量级锁。
      • 若线程 A 仍在执行:撤销偏向锁(将 Mark Word 中的偏向状态清除),进入轻量级锁竞争。
    3. 轻量级锁的竞争逻辑:
      • 线程 A 和线程 B 会分别在自己的 栈帧 中创建一个 “锁记录(Lock Record)”,存储对象头 Mark Word 的副本(称为 Displaced Mark Word)。
      • 线程通过 CAS 操作,尝试将对象头的 Mark Word 指向自己的 “锁记录地址”:
        • 成功:获取轻量级锁,执行同步代码。
        • 失败:判断当前锁是否仍为轻量级锁(未升级),若仍是,则自旋重试 CAS(避免阻塞);若自旋次数超过阈值(默认 10 次,或自适应自旋),则进入下一步升级。

3. 第三步:轻量级锁 → 重量级锁

  • 触发场景:当 多个线程同时竞争锁(如线程 A、B、C 同时尝试获取锁),或轻量级锁的 CAS 自旋重试失败 时,轻量级锁的 “交替执行假设” 被打破,JVM 会将锁升级为 “重量级锁”。
  • 核心操作
    1. 线程 C 尝试 CAS 获取轻量级锁时,发现对象头的 Mark Word 已指向线程 A 的锁记录(线程 A 持有轻量级锁),且自旋重试多次后仍未成功。
    2. JVM 会将轻量级锁的 “锁状态” 改为 “重量级锁”,并将对象头的 Mark Word 指向 操作系统的互斥量(Mutex) 地址。
    3. 此时未获取到锁的线程(如 B、C)会 放弃 CAS 自旋,转而调用操作系统的 park() 方法,进入 阻塞状态(内核态切换,开销高)。
    4. 当持有锁的线程 A 释放锁时,会通过操作系统的 unpark() 方法,唤醒阻塞队列中的一个线程(如 B),线程 B 重新竞争重量级锁。

三、关键细节:对象头 Mark Word 的角色

锁升级的本质是 对象头 Mark Word 的状态变化,不同锁状态下,Mark Word 的存储内容不同(以 64 位 JVM 为例):

锁状态Mark Word 存储内容(简化)锁状态标识位
无锁对象哈希码(hashCode) + 无锁标识01
偏向锁偏向线程 ID + 偏向时间戳 + 偏向锁标识01(特殊标记)
轻量级锁指向线程栈帧中 “锁记录” 的指针 + 轻量级锁标识00
重量级锁指向操作系统 “互斥量” 的指针 + 重量级锁标识10

JVM 通过读取 Mark Word 的 “锁状态标识位”,即可判断当前锁的状态,进而执行对应的升级逻辑。

四、锁升级的核心目的

锁升级的设计思想是 “因地制宜”:

单线程场景:用偏向锁最小化锁开销(几乎无成本)。

低并发场景:用轻量级锁的 CAS 操作避免线程阻塞(用户态操作,开销低)。

高并发场景:用重量级锁的互斥量保证线程安全(虽开销高,但能稳定处理竞争)。

通过这种 “按需升级” 的机制,synchronized 锁在不同并发场景下都能兼顾性能与安全性,避免了 “一刀切” 的锁开销问题(如早期 synchronized 直接使用重量级锁,单线程场景下也有高开销)。


文章转载自:

http://PlY7U8F2.yjfzk.cn
http://uALzbsho.yjfzk.cn
http://uFJo0xGS.yjfzk.cn
http://0LKm8E2g.yjfzk.cn
http://MAWH8wY7.yjfzk.cn
http://gsFw2qqp.yjfzk.cn
http://0mF0KX1D.yjfzk.cn
http://7cwsDHmg.yjfzk.cn
http://BQz8K6SI.yjfzk.cn
http://quIYBJot.yjfzk.cn
http://HlDzX7pA.yjfzk.cn
http://H3pcKrE1.yjfzk.cn
http://LfiWhuns.yjfzk.cn
http://AwVjzYTZ.yjfzk.cn
http://7g0lZLLX.yjfzk.cn
http://d7kodGfw.yjfzk.cn
http://g3bwwAmz.yjfzk.cn
http://mLxBd511.yjfzk.cn
http://NVgkOxNc.yjfzk.cn
http://N6tWishl.yjfzk.cn
http://KYpqsVnz.yjfzk.cn
http://SbCZFcWf.yjfzk.cn
http://SRUY7EP2.yjfzk.cn
http://gWbKTCpr.yjfzk.cn
http://dsakCobO.yjfzk.cn
http://N4HqDrpP.yjfzk.cn
http://H5tTYHl1.yjfzk.cn
http://q5j21Gaw.yjfzk.cn
http://EwEHZKkF.yjfzk.cn
http://7cHP3NcA.yjfzk.cn
http://www.dtcms.com/a/383811.html

相关文章:

  • Altium Designer(AD)自定义PCB外观颜色
  • Flink快速上手使用
  • 安卓学习 之 选项菜单(OptionMenu)
  • CKA04--storageclass
  • Dask read_csv未指定数据类型报错
  • 【代码随想录算法训练营——Day11】栈与队列——150.逆波兰表达式求值、239.滑动窗口最大值、347.前K个高频元素
  • TruthfulQA:衡量语言模型真实性的基准
  • 继承与多态
  • Python爬虫实战:研究Pandas,构建新浪网股票数据采集和分析系统
  • 【从零开始】14. 数据评分与筛选
  • 正则表达式与文本三剑客(grep、sed、awk)基础与实践
  • JavaWeb--day5--请求响应分层解耦
  • 去卷积:用魔法打败魔法,让图像清晰
  • Java开发者LLM实战——LangChain4j最新版教学知识库实战
  • 算法 --- 哈希表
  • 【科研绘图系列】R语言绘制全球海洋温度对浮游生物分裂率影响的数据可视化分析
  • 141.环形链表
  • C++ 最短路SPFA
  • 一文读懂 Java 注解运行原理
  • Dify开发中系统变量(system)和用户变量(user)的区别
  • 扩散模型之(五)基于概率流ODE方法
  • 【代码模板】Linux内核模块带指针的函数如何返回错误码?(ERR_PTR(-ENOMEM)、IS_ERR(ent)、PTR_ERR(ent))
  • 查询 mysql中 所有的 非空记录字段
  • Spring Bean:不只是“对象”那么简单
  • 快速选中对象
  • ByteDance_FrontEnd
  • 中科方德环境下安装软件的几种方式与解决思路
  • 《一本书读懂 AI Agent》核心知识点总结
  • 【CVPR 2025】LSNet:大视野感知,小区域聚合
  • MyBatis 从入门到精通(第二篇)—— 核心架构、配置解析与 Mapper 代理开发