锁升级是 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://www.pswp.cn/diannao/99128.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/99128.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/99128.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HOT100--Day25--84. 柱状图中最大的矩形,215. 数组中的第K个最大元素,347. 前 K 个高频元素

HOT100–Day25–84. 柱状图中最大的矩形,215. 数组中的第K个最大元素,347. 前 K 个高频元素 每日刷题系列。今天的题目是《力扣HOT100》题单。 题目类型:栈,堆。 84. 柱状图中最大的矩形 思路: class Solution {publ…

基于 Apache Doris 的用户画像数据模型设计方案

一、 需求分析与设计目标数据源:用户基本信息:用户ID、性别、出生日期、注册时间、常驻地域(省、市、区)、职业等。用户体检报告:每次体检的报告ID、体检时间、各项指标(如血压、血糖、血脂、BMI等&#xf…

Python的深度学习

深入理解Python高级特性掌握Python的高级特性是进阶的关键,包括装饰器、生成器、上下文管理器、元类等。这些特性能够提升代码的灵活性和效率。例如,装饰器可以用于实现AOP(面向切面编程),生成器可以处理大数据流而无需…

数据库范式(Normalization)

一个设计混乱的数据库就像一个杂乱的房间,用起来非常不方便:东西到处乱放(数据冗余),找件东西要翻遍所有角落(查询困难),扔掉一把旧椅子时,可能会把搭在上面的唯一一件外…

数据结构---循环队列

基于循环数组实现的循环队列解决了顺序队列中的假溢出导致的空间浪费问题操作:(1)初始化//循环队列 typedef struct {int *data;//指针模拟声明数组int head,tail;//队头,队尾 }Queue; //初始化 Queue *InitQueue() {Queue *q (Q…

深入理解线程模型

线程作为操作系统调度的基本执行单元,是实现高吞吐、低延迟系统的基础。一、进程与线程的体系结构对比核心概念:进程(Process):操作系统资源分配的基本单位,拥有独立的虚拟地址空间、文件描述符表、环境变量…

TTC定时器中断——MPSOC实战3

开启TTC定时器&#xff0c;不同于7000系列的私有定时器此处设置LPD_LSBUS频率TTC频率取决于LPD_LSBUS可前往指定位置查看参数不使能填写对应宏可前往指定位置查看参数main.c#include <stdio.h> #include "xparameters.h" #include "xgpiops.h" #incl…

人工智能训练师三级备考笔记

一、实操1&#xff09;通用语法&#xff08;常见于实操题第一块代码块&#xff09;1.读取文件数据或加载数据集等描述时一般为以下结构&#xff1a;Datapd.read_文件格式(文件名) 注意&#xff1a;文件名需要用‘ ’框起来&#xff0c;必须要有引号文件格式有以下内容csv、txt…

Cherry Studio递归工具调用机制深度解析

在现代AI应用开发中,工具调用(Tool Calling)已成为大语言模型与外部系统交互的核心机制。Cherry Studio作为一款先进的AI对话客户端,实现了一套完整的递归工具调用系统,能够让AI助手在执行复杂任务时自动调用多个工具,并根据执行结果智能决策下一步操作。本文将深入解析这…

[哈希表]966. 元音拼写检查器

966. 元音拼写检查器 class Solution:def spellchecker(self, wordlist: List[str], queries: List[str]) -> List[str]:origin set(wordlist) # 存储原始单词用于完全匹配lower_to_origin {} # 存储小写形式到原始单词的映射vowel_to_origin {} # 存储元音模糊形…

正则表达式与文本三剑客(grep、sed、awk)基础与实践

正则表达式基础与实践一、正则表达式概述1. 定义正则表达式&#xff08;Regular Expression&#xff0c;简称 RE&#xff09;是用于描述字符排列和匹配模式的语法规则&#xff0c;核心作用是对字符串进行分割、匹配、查找、替换操作。它本质是 “模式模板”&#xff0c;Linux 工…

eclipse中web项目编译后的lib里面jar为空问题处理

1. 检查项目构建配置验证项目性质右键单击项目 → Properties确认项目已正确配置&#xff1a;​Project Facets​&#xff1a;确保已勾选"Dynamic Web Module"​Targeted Runtimes​&#xff1a;确保已选择服务器运行时&#xff08;如Tomcat&#xff09;检查部署程序…

C语言中的递归问题——汉诺塔问题

汉诺塔&#xff08;Tower of Hanoi)&#xff0c;又称河内塔&#xff0c;是一个源于印度古老传说的益智玩具。传说大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在…

ArkAnalyzer源码初步分析I——分析ts项目流程

1.前言&#xff1a; 鸿蒙程序分析框架ArkAnalyzer&#xff08;方舟分析器&#xff09; 源码地址 入门文档 2.阅读入门文档后&#xff1a; 本人具有一定的Java开发经验。虽然我对 TypeScript&#xff08;TS&#xff09;和 ArkTS 还不熟&#xff0c;但很多概念对我这个 Java 开…

c#基础二(类和对象,构造器调用顺序、访问级别、重写和多态、抽象类和接口)

一、类1.0对象初始化器class Student {public String name;public int age { get; set; } } internal class Program {static void Main(string[] args){ //写法一Student stunew Student();stu.name"Tom";stu.age20;//写法二Student stu2 new Student { name &qu…

Qt之快捷键、事件处理、自定义按键——完成记事本项目

快捷键我们电脑中的记事本中还支持快捷键&#xff0c;如“CTRLO”打开文件、“CTRLS”保存文件在Qt中使用QShortcut这个类创建快捷键在.cpp文件的构造函数中创建QShortcut对象&#xff0c;绑定打开文件和保存文件的槽函数放大缩小字体还是在.cpp的构造函数中编写代码Widget::Wi…

Open cascade中如何使用BRepAlgoAPI_Splitter分割一个Face

理论介绍 在OpenCASCADE几何建模内核中&#xff0c;BRepAlgoAPI_Splitter是一个强大的工具&#xff0c;用于将一个形状&#xff08;Shape&#xff09;用另一个形状&#xff08;Tool&#xff09;进行分割。这种操作在CAD建模中非常常见&#xff0c;比如用平面切割实体、用曲线分…

【医疗 AI】Baichuan-M2 医疗大模型:技术解读与使用方法

【医疗 AI】Baichuan-M2 医疗大模型&#xff1a;技术解读与使用方法1. Baichuan-M2 医疗大模型简介1.1 基本信息1.2 下载地址1.3 技术特点2. Baichuan-M2 模型技术报告2.1 摘要2.2 医学性能评估2.2.1 HealthBench基准2.2.2 中国医疗场景对比评估2.3 系统架构2.3.1 验证器系统2.…

unity pcd 二进制版 简单显示文件对象(单色)

unity Point Cloud Viewer and Tool 那个插件不支持pcd二进制&#xff0c;而且网上到处都是AI 我恨这种AI滥用&#xff0c;提供不了一点价值 好了&#xff0c;言归正传 可以在Point Cloud Viewer and Tool这个插件报错地方转用这个代码&#xff0c;具体咋结合请自行研究。 …

强大的开源文档问答工具-Kotaemon

Kotaemon 是一个基于 RAG&#xff08;Retrieval-Augmented Generation&#xff09;架构的开源文档问答工具&#xff0c;为用户提供与文档对话的智能交互体验。该项目同时服务于终端用户和开发者&#xff0c;具有高度的可扩展性和定制化能力。技术栈分析核心技术栈后端框架Pytho…