详细了解 synchronized 锁升级过程

ArcGIS天地图矢量化秘籍:用重分类+ArcScan高效提取建筑轮廓线 本文详细介绍了利用ArcGIS重分类和ArcScan技术高效提取天地图建筑轮廓线的半自动化流程。通过动态中断值计算、多级重分类策略和ArcScan高级矢量化技巧,显著提升城市规划中的矢量化效率与精度,适用于中级GIS用户。 阅读详情

Python微信订餐小程序课程视频

https://edu.youkuaiyun.com/course/detail/36074

Python实战量化交易理财系统

https://edu.youkuaiyun.com/course/detail/35475

前言

首先,synchronized 是什么?我们需要明确的给个定义——同步锁,没错,它就是把锁。

可以用来干嘛?锁,当然当然是用于线程间的同步,以及保护临界区内的资源。我们知道,锁是个非常笼统的概念,像生活中有指纹锁、密码锁等等多个种类,那 synchronized 代表的锁具体是把什么锁呢?

答案是—— Java 内置锁。在 Java 中,每个对象中都隐藏着一把锁,而 synchronized 关键字就是激活这把隐式锁的把手(开关)。

先来简单了解一下 synchronized,我们知道其共有 3 种使用方式:

Synchronized 的使用Synchronized 的使用

  • 修饰静态方法:锁住当前 class,作用于该 class 的所有实例
  • 修饰非静态方法:只会锁住当前 class 的实例
  • 修饰代码块:该方法接受一个对象作为参数,锁住的即该对象

使用方法就不在这里赘述,可自行搜索其详细的用法,这不是本篇文章所关心的内容。

知道了 synchronized 的概念,回头来看标题,它说的锁升级到底是个啥?对于不太熟悉锁升级的人来说,可能会想:

所谓锁,不就是啪一下锁上就完事了吗?升级是个什么玩意?这跟打扑克牌也没关系啊。

对于熟悉的人来说,可能会想:

不就是「无锁 ==> 偏向锁 ==> 轻量级锁 ==> 重量级锁 」吗?

你可能在很多地方看到过上面描述的锁升级过程,也能直接背下来。但你真的知道无锁、偏向锁、轻量级锁、重量级锁到底代表着什么吗?这些锁存储在哪里?以及什么情况下会使得锁向下一个 level 升级?

想知道答案,我们似乎必须先搞清楚 Java 内置锁,其内部结构是啥样的?内置锁又存放在哪里?

答案在开篇提到过——在 Java 对象中。

那么现在的问题就从「内置锁结构是啥」变成了「Java 对象长啥样」。

对象结构

从宏观上看,Java 对象的结构很简单,分为三部分:

Java 对象结构Java 对象结构
从微观上看,各个部分都还可以深入展开,详见下图:

Java 详细对象结构Java 详细对象结构
接下来分别深入讨论一下这三部分。

对象头

从脑图中可以看出,其由 Mark Word、Class Pointer、数组长度三个字段组成。简单来说:

  • Mark Word:主要用于存储自身运行时数据
  • Class Pointer:是指针,指向方法区中该 class 的对象,JVM 通过此字段来判断当前对象是哪个类的实例
  • 数组长度:当且仅当对象是数组时才会有该字段

Class Pointer 和数组长度没什么好说的,接下来重点聊聊 Mark Word。

Mark Word 所代表的「运行时数据」主要用来表示当前 Java 对象的线程锁状态以及 GC 的标志。而线程锁状态分别就是无锁、偏向锁、轻量级锁、重量级锁。

所以前文提到的这 4 个状态,其实就是 Java 内置锁的不同状态。

在 JDK 1.6 之前,内置锁都是重量级锁,效率低下。效率低下表现在

而在 JDK 1.6 之后为了提高 synchronized 的效率,才引入了偏向锁、轻量级锁。

随着锁竞争逐渐激烈,其状态会按照「无锁 ==> 偏向锁 ==> 轻量级锁 ==> 重量级锁 」这个方向逐渐升级,并且不可逆,只能进行锁升级,而无法进行锁降级。

接下来我们思考一个问题,既然 Mark Word 可以表示 4 种不同的锁状态,其内部到底是怎么区分的呢?(由于目前主流的 JVM 都是 64 位,所以我们只讨论 64 位的 Mark Word)接下来我们通过图片直观的感受一下。

(1)无锁

无锁无锁
这个可以理解为单线程很快乐的运行,没有其他的线程来和其竞争。

(2)偏向锁

偏向锁偏向锁
首先,什么叫偏向锁?举个例子,一段同步的代码,一直只被线程 A 访问,既然没有其他的线程来竞争,每次都要获取锁岂不是浪费资源?所以这种情况下线程 A 就会自动进入偏向锁的状态。

后续线程 A 再次访问同步代码时,不需要做任何的 check,直接执行(对该线程的「偏爱」),这样降低了获取锁的代价,提升了效率。

看到这里,你会发现无锁、偏向锁的 lock 标志位是一样的,即都是 01,这是因为无锁、偏向锁是靠字段 biased_lock 来区分的,0 代表没有使用偏向锁,1 代表启用了偏向锁。为什么要这么搞?你可以理解为无锁、偏向锁在本质上都可以理解为无锁(参考上面提到的线程 A 的状态),所以 lock 的标志位都是 01 是没毛病的。

PS:这里的线程 ID 是持有当前对象偏向锁的线程

(3)轻量级锁

轻量级锁轻量级锁
但是,一旦有第二个线程参与竞争,就会立即膨胀为轻量级锁。企图抢占的线程一开始会使用自旋:


的方式去尝试获取锁。如果循环几次,其他的线程释放了锁,就不需要进行用户态到内核态的切换。虽然如此,但自旋需要占用很多 CPU 的资源(自行理解汽车空档疯狂踩油门)。如果另一个线程 一直不释放锁,难道它就在这一直空转下去吗?

当然不可能,JDK 1.7 之前是普通自旋,会设定一个最大的自旋次数,默认是 10 次,超过这个阈值就停止自旋。JDK 1.7 之后,引入了适应性自旋。简单来说就是:这次自旋获取到锁了,自旋的次数就会增加;这次自旋没拿到锁,自旋的次数就会减少。

(4)重量级锁

重量级锁重量级锁
上面提到,试图抢占的线程自旋达到阈值,就会停止自旋,那么此时锁就会膨胀成重量级锁。当其膨胀成重量级锁后,其他竞争的线程进来就不会自旋了,而是直接阻塞等待,并且 Mark Word 中的内容会变成一个监视器(monitor)对象,用来统一管理排队的线程。

这个 monitor 对象,每个对象都会关联一个。monitor 对象本质上是一个同步机制,保证了同时只有一个线程能够进入临界区,在 HotSpot 的虚拟机中,是由 C++ 类 ObjectMonitor 实现的。

那么 monitor 对象具体是如何来管理线程的?接下来我们看几个 ObjectMonitor 类关键的属性:

  • ContentionQueue:是个队列,所有竞争锁的线程都会先进入这个队列中,可以理解为线程的统一入口,进入的线程会阻塞。
  • EntryList:ContentionQueue 中有资格的线程会被移动到这里,相当于进行一轮初筛,进入的线程会阻塞。
  • Owner:拥有当前 monitor 对象的线程,即 —— 持有锁的那个线程。
  • OnDeck:与 Owner 线程进行竞争的线程,同一时刻只会有一个 OnDeck 线程在竞争。
  • WaitSet:当 Owner 线程调用 wait() 方法被阻塞之后,会被放到这里。当其被唤醒之后,会重新进入 EntryList 当中,这个集合的线程都会阻塞。
  • Count:用于实现可重入锁,synchronized 是可重入的。

对象体

对象体包含了当前对象的字段和值,在业务中u l是较为核心的部分。

对齐字节

就是单纯用于填充的字节,没有其他的业务含义。其目的是为了保证对象所占用的内存大小为 8 的倍数,因为HotSpot VM 的内存管理要求对象的起始地址必须是 8 的倍数。

锁升级

了解完 4 种锁状态之后,我们就可以整体的来看一下锁升级的过程了。

线程 A 进入 synchronized 开始抢锁,JVM 会判断当前是否是偏向锁的状态,如果是就会根据 Mark Word 中存储的线程 ID 来判断,当前线程 A 是否就是持有偏向锁的线程。如果是,则忽略 check,线程 A 直接执行临界区内的代码。

但如果 Mark Word 里的线程不是线程 A,就会通过自旋尝试获取锁,如果获取到了,就将 Mark Word 中的线程 ID 改为自己的;如果竞争失败,就会立马撤销偏向锁,膨胀为轻量级锁。

后续的竞争线程都会通过自旋来尝试获取锁,如果自旋成功那么锁的状态仍然是轻量级锁。然而如果竞争失败,锁会膨胀为重量级锁,后续等待的竞争的线程都会被阻塞。

锁升级过程锁升级过程

EOF

其实偏向锁还有一个撤销的过程,也是有代价的,但相比于偏向锁带好的好处,是能够接受的。但我们这里重点的还是关注锁升级的具体逻辑和细节,关于锁升级的过程就聊到这里。

欢迎 wx 搜索关注 「SH的全栈笔记」

  • END -
深入解析ChangeFormer:基于Transformer的孪生网络在遥感变化检测中的创新应用 本文深入解析了ChangeFormer这一基于Transformer的孪生网络在遥感变化检测中的创新应用。通过分层Transformer编码器、特征差异计算模块和轻量级MLP解码器的设计,ChangeFormer在LEVIR-CD数据集上取得了90.4%的F1分数,显著优于传统卷积网络。文章还详细探讨了工程化实现、训练调参和模型部署的优化策略,为遥感变化检测领域提供了新的技术范式。 阅读详情

相关推荐

振动信号相位测量的关键技术解析

本文深入解析了振动信号相位测量的关键技术,强调相位是振动信号的“身份证”,对于动平衡和故障诊断至关重要。文章详细阐述了键相传感器与振动传感器的选型、安装要点,以及时域和频域(FFT)核心算法,并针对现场噪声、转速波动等挑战提供了实战解决方案,帮助工程师实现精准、稳定的相位测量。

vv45678的博客 839

python实现synchronized

利用python的装饰器实现类似java中的synchronized from threading import Lock,Thread from functools import wraps default_lock=Lock() lock_list={'default':Lock()} def synchronized(func=None,obj=None): if func i...

a1053904672的博客 4994

AF3 ProteinDataset类的_patch方法解读

AlphaFold3 protein_dataset模块 ProteinDataset 类  _patch 方法的主要目的是围绕锚点残基(anchor residues)裁剪蛋白质数据,提取一个局部补丁(patch)作为模型输入。

qq_27390023的博客 1148

线程安全问题 synchronized (原子性 (可见性 防止指令重排(volatile)))

线程安全问题 synchronized volatile(原子性 可见性 防止指令重排)

m0_46427670的博客 495

MediaPipeUnityPlugin(最新版)摇摆拳人脸识别

MediaPipeUnityPlugin(最新版)摇摆拳人脸识别

不忘初心 方得始终 2984

ZYNQ 系统的IEEE1588 实现方法

zynq IEEE588/PTP 实现方案(讨论稿)

姚家湾博客 1万+

python原子性_synchronized使用及java中的原子性问题

1.Synchronized关键字使用class X {// 修饰非静态方法synchronized void foo() {// 临界区}// 修饰静态方法synchronized static void bar() {// 临界区}// 修饰代码块Object obj = new Object();void baz() {synchronized(obj) {// 临界区}}}说明:修饰静态方...

weixin_36334284的博客 496

飞秒激光加工石英玻璃的COMSOL多物理场仿真研究

多物理场仿真是现代工程研发的重要工具,通过耦合电磁、热传导和流体力学等物理场,可以准确预测复杂工况下的材料行为。COMSOL Multiphysics作为主流仿真平台,其双温模型能精确描述飞秒激光加工中的电子-声子耦合过程。这种仿真技术可显著降低实验成本,在微纳加工领域尤为关键。针对石英玻璃这类光学材料,仿真能有效优化激光参数,实现亚微米级精度的冷加工。研究显示,结合移动网格技术和自定义材料状态函数,可以准确预测烧蚀形貌与热影响区分布,为光学器件和微流控芯片制造提供可靠工艺指导。

weixin_29290863的博客 240

Python里面有没有synchronized?

**Python 没有 `synchronized` 关键字**,但可以通过 `threading.Lock`、`RLock` 或自定义装饰器实现类似功能。- 也可以手动调用 `lock.acquire()` 和 `lock.release()`。- **`threading.Semaphore`**:限制同时访问的线程数量。- **`threading.Condition`**:用于线程间的条件通知。- **`threading.Barrier`**:同步多个线程的进度。

xioayanran123的博客 613

别再只看成交量了!用通达信这个VOL监测公式,一眼识别主力吸筹与出货信号

本文详细介绍了通达信VOL监测公式的实战应用,通过彩色量柱和换手率分层技术,帮助投资者识别主力吸筹与出货信号。该公式结合动态量能标准化和多周期均线组合,提供可视化主力行为图谱,提升交易决策的准确性。

weixin_28693447的博客 664

将 SAP BTP ABAP environment 与 SAP S/4HANA Cloud 公有云版集成:从架构理念到落地实战

本文探讨了在SAP云环境中实现ABAP扩展应用与S/4HANA Cloud系统集成的技术方案。通过建立标准化的远程通信通道,开发者可在SAP BTP ABAP环境中开发扩展应用,同时安全访问S/4HANA Cloud的核心业务数据和服务。文章详细介绍了整体架构设计、开发实现步骤(包括定义通信场景、生成服务消费模型和编写调用代码)以及管理员在S/4HANA侧的配置工作(创建通信安排和技术用户)。通过一个业务伙伴自助注册平台的案例,展示了如何在不修改标准系统的情况下实现云扩展,体现了SAP"干净核心&

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 241

细论Synchronize的使用区别

Synchronize的作用 在并发编程中实现共享数据的同步。 Synchronize使用形式 Synchronize的使用方式大体分为两种:Synchronize同步方法 以及 Synchronize块。其本质都是对目标对象(或类)的锁定,让该方法变为原子操作。

Ryan的博客 1095

芯片标称具备8kVESD能力却在8kV测试中失效?

芯片级ESD(HBM模型)与系统级ESD(IEC 61000-4-2)存在本质差异:

硬核科技 647

详细了解 Synchronized 锁升级过程【并发编程】

1.Synchronized 作用 修饰静态方法:锁住当前 class,作用于该 class 的所有实例 修饰非静态方法:只会锁住当前 class 的实例 修饰代码块:该方法接受一个对象作为参数,锁住的即该对象 2.锁升级 synchronized锁有四种状态,无锁,偏向锁,轻量级锁,重量级锁,这几个状态会随着竞争状态逐渐升级,锁可以升级但不能降级,但是偏向锁状态可以被重置为无锁状态 「无锁 ==> 偏向锁 ==> 轻量级锁 ==> 重量级锁 」 3.对象头 4.synchron

不积跬步,无以至千里;不积小流,无以成江海。 957

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

关于Synchronized的偏向锁,轻量级锁,重量级锁,锁升级过程,自旋优化,你该了解这些

目录 前言 可见性问题及解决 概念描述 代码展示 分析 synchronized如何解决可见性 原子性问题及解决 概念描述 代码展示 分析 synchronized如何解决原子性问题 有序性问题及解决 概念描述 代码展示 synchronized如何解决有序性问题 synchronized的常见使用方式 修饰代码块(同步代码块) 修饰方法 synchroni...

路漫漫其修远兮,吾将上下而求索。 1596

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

4.7 synchronized底层实现、锁升级过程和实例锁跟类锁的区别,以及与Lock的区别(需要深入了解);

在4.5中已经写到了synchronized底层实现,以前也写过锁升级过程 实例锁和类锁的区别 参考博客:https://www.cnblogs.com/fengzheng/p/12066239.html 类锁 类锁是加载类上的,而类信息是存在 JVM 方法区的,并且整个 JVM 只有一份,方法区又是所有线程共享的,所以类锁是所有线程共享的。 使用类锁的方式有如下方式:1、锁住类中的静态变量 因为静态变量和类信息一样也是存在方法区的并且整个 JVM 只有一份,所以加在静态变量上可以达到类锁的目的

服务端开发进阶之路 251

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

多线程Synchronized关键字-------你所不了解的锁升级过程(内附详细原理图)

本文主要介绍Sync锁的升级过程以及介绍锁信息,其中的CAS,MarkWord,偏向锁,轻量级锁…等知识点的讲解,不讲解锁的其他优化,其他锁优化会在下一篇进行讲解。 1.什么是Synchronized关键字? synchronized关键字用来解决多线程之间访问资源的同步问题,它可以保证被它修饰的方法或者代码块在任何时刻只有一个线程能够执行。 在 Java 早期版本中,synchronized属于...

AY_G的博客 1477

在c#中用mutex类实现线程的互斥_面试官经常问的synchronized实现原理和锁升级过程,你真的了解吗...

本篇文章主要从字节码和JVM底层来分析synchronized实现原理和锁升级过程,其中涉及到了简单认识字节码、对象内部结构以及ObjectMonitor等知识点。阅读本文之前,如果大家对synchronized关键字的基本使用还不是很了解的话,推荐阅读笔者之前的一遍关于synchronized关键字使用的文章:synchronized三种使用方式都不知道还想通过面试,门都没有从字节码角度分析sy...

weixin_39576133的博客 294

30分钟彻底弄懂 synchronized 锁升级过程

点击关注公众号,实用技术文章及时了解在Java的并发编程领域中,我们进行会使用到锁这个东西,例如在多线程环境下为了预防某些线程安全问题,这里面可能会产生一些预想不到的问题,所以下边我整理了一系列关于JDK中锁的问题,帮助大家更加深入地了解它们。synchronized真的是重量级锁嘛?这个问题相信大部分人在面试的时候都有遇到过,答案是否定的。这个要看JDK的版本来进行判断...

Java知音 1063

【<synchronized锁升级>】

synchronized锁升级[1] Java对象头[2] Mark word 结构[3] Monitor[4] synchronized锁升级无锁偏向锁(可关闭)轻量级锁重量级锁[5] synchronized锁流程[6] synchronized锁对比 [1] Java对象头 我们以 Hotspot 虚拟机为例,Hopspot 对象头主要包括两部分数据:Mark Word(标记字段) 和 Klass Pointer(类型指针) Mark Word:默认存储对象的HashCode,分代年龄和锁标志位信息。

徐明晓的博客 700

synchronized锁升级_Synchronized的锁升级之路

读完本文,可以知道Java Synchronized锁都有哪几种状态,以及这几种状态的锁升级流程细节,这很有可能就解决了下次面试中的问题呦 :)关于Java中Synchronized,几乎是最简单常用的并发同步基础组件了,但是计算机程序的并发可不是简单的问题,那么Synchronized是如何解决并发及其性能问题的呢?Synchronized在Java JVM里的实现是基于进入和退出Monitor...

weixin_39563823的博客 58

Synchronized锁升级过程 学习笔记

1. 对象的存储方式对象头Mark Word(标记字段)Klass Pointer(类型指针)实例变量填充数据2. Mark Word与Synchronized锁的关系Mark Word的数据字段锁标志位没有锁 11无锁 001偏向锁 101轻量级锁 00自旋次数达到上限线程C尝试竞争锁对象重量级锁 10 1. 对象的存储方式 要明白Synchronized锁升级过程前,我们要先知道对象在堆内存中的存储模型; 堆内存中的对象分为了三块,对象头、实例变量和填充字节; 对象头 对象头主要包含两个部分 1. .

qq_43564410的博客 856

Synchronized与锁升级

synchronized 锁 用锁能够实现数据的安全性,但是会带来性能下降,无锁能够基于线程并行提升程序性能,但是会带来安全性下降。 锁的升级过程: 无锁—>偏向锁----> 轻量锁----->重量锁 synchronized 锁: 由对象头中的Mark Word 更具锁标志位的不同而被复用及锁升级策略 java5以前,只有synchronized ,这个是操作系统级别的重量级操作, 重量级锁,假如锁的竞争比较激烈的话,性能下降,java5之前,用户态和内核态之间的切换 java的线程是映

散步的博客 264

Java并发——Synchronized关键字和锁升级

Synchronized使用场景 Synchronized是一个同步关键字,在某些多线程场景下,如果不进行同步会导致数据不安全,而Synchronized关键字就是用于代码同步。什么情况下会数据不安全呢,要满足两个条件:一是数据共享(临界资源),二是多线程同时访问并改变该数据。 Synchronized锁的3种使用形式: Synchronized修饰普通同步方法:锁对象当前实例对象; Synchr...

glamour2015的博客 304
上一篇: Ajax 实战(一)
下一篇: 【spring源码系列】之【Bean的销毁】
pythonxxoo
博客等级 码龄5年 337粉丝 670原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值