JUC并发编程之Synchronized锁优化

news2024/11/19 14:50:05

目录

1. Java对象头

 2. Synchronized锁优化

2.1 偏向锁

2.2 轻量级锁

 2.3 重量级锁

2.4 各种锁对比

1. Java对象头

HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

对象头是对象在内存中的元数据信息,它包含了对象的一些重要信息,如对象的锁状态、类元数据指针、数组长度等。对象头是Java虚拟机(JVM)管理和操作对象的关键部分。

Java对象头通常包括以下信息:

  1. Mark Word(标记字):Mark Word是对象头中最重要的部分,占据了对象头的大部分空间。它包含了对象的哈希码、锁信息、垃圾回收信息等。Mark Word的具体结构因JVM实现而异,通常包括以下内容:

    • 对象标志位:用于标识对象的状态,例如是否被锁定、是否已经被回收等。
    • 哈希码:用于支持hashCode方法,以及在哈希表中查找对象的位置。
    • 分代年龄:用于垃圾回收的分代算法,标记对象所属的年代。
    • 锁信息:用于支持同步操作,包括偏向锁、轻量级锁和重量级锁的状态信息。
  2. 类型指针:类型指针指向对象的类元数据,它用于确定对象所属的类,以支持对象的方法调用和字段访问。

  3. 数组长度(仅对数组对象有效):如果对象是数组,对象头中会包括数组长度信息。

对象头的结构和大小可能会因不同的JVM实现和对象类型而异。对象头通常占用一定的内存空间,因此它会增加每个对象的内存开销。对象头的信息对于垃圾回收、同步和虚拟机运行时的对象操作非常重要。其中Mark Word结构如下图所示。

 2. Synchronized锁优化

jdk1.6之前,synchronized属于重量级锁(悲观锁) ,jdk1.6之后被进行了大幅度优化,支持锁升级制度缓解加锁和解锁造成的性能费,锁的级别采用: 偏向锁 -> 轻量级锁 -> 重量级锁。

  • 原子性: synchronized依靠两个字节码指令monitorentermonitorexit,可以保证被synchronized修饰的代码在同一时间只能被一个线程访问

  • 可见性: JMM(Java内存模型)规定,内存主要分为主内存和工作内存两种,每个线程拥有不同的工作内存,线程工作时会从主内存中拷贝一份变量到工作内存中。代码执行后,有时工作内存中的变量无法及时刷新到主内存中,或者工作内存无法及时获取主内存的最新值,导致共享变量在不同线程间处于不可见性,由此JMM对synchronized做了2条规定:

    a.线程解锁前,必须把变量的最新值刷新到主内存中。

    b.线程加锁时,先清空工作内存中的变量值,从主内存中重新获取最新值到工作内存中

  • .有序性: 有时候编译器和处理器为了提升代码效率,会进行指令重排序,但是as-if-serial规定无论怎么重排序,单线程程序的执行结果都不能被改变,而synchronized保证了被修饰的程序在同一时间内只能被同一线程访问, 所以其也算是保证了有序性,但synchronized实际上并不是禁止了被修饰的代码指令重排序。

2.1 偏向锁

偏向锁的思想是,如果一个线程获得了锁,那么锁就进入偏向模式,此时,Mark Word的结构也变为偏向锁结构,当这个线程再次请求锁时,无需再做任何同步操作即可再次获取锁,这样就省去了大量有关锁申请的操作,从而也就提供程序的性能。所以对于没有锁竞争的场合,偏向锁有很好的优化效果,但是在有多线程竞争锁的场合,偏向锁就失效了,这种场合下不应该使用偏向锁,否则会得不偿失,偏向锁失败后,将会优先升级为轻量级锁 基本工作过程:
当线程A访问代码块并获取锁对象时,会通过CAS在Mark Word中记录偏向的锁的threadID,因为偏向锁不会主动释放锁,因此以后再次获取锁的时候,需要比较当前线程的 threadID 和 Mark Word 中的threadID是否一致,如果一致,则无需使用CAS来加锁、解锁;如果不一致,则是因为有其他线程如线程b 来竞争该锁,而偏向锁时不会主动释放锁,因此 Mark Word 存储的还是 线程a 的threadID,那么需要查看 Mark Word 中记录的 线程a 是否存活,如果没有存活,那么锁对象被重置为无锁状态,线程b 可以竞争将其设置为偏向锁;如果存活,那么立刻查找线程a的栈帧信息,如果还是需要继续持有这个锁, 那么暂停当前线程a,撤销偏向锁,升级为轻量级锁,如果 线程不再使用该锁,那么将锁状态设为无锁状态,重新偏向新的线程。

在java中偏向锁是默认开启的,绝大多数 情况下,对于加锁的程序大多都会有两个以上的线程去竞争,如果开启偏向锁,反而会加剧锁的资源消耗,可以通过jvm参数启动或关闭偏向锁:

-XX:-UseBiasedLocking = false
    //偏向锁的启动延迟默认为5秒,可以取消这个延迟:
XX:BiasedLockingStartUpDelay=0

2.2 轻量级锁

当多个线程竞争同一个锁时,偏向锁将转化为轻量级锁。轻量级锁通过CAS(Compare and Swap)操作来尝试获取锁,而不会让线程阻塞。如果CAS操作成功,线程获得锁;否则,线程将升级为重量级锁。轻量级锁是由偏向锁升级而来,它考虑的情况是竞争锁的线程不多,而且线程持有锁的时间也不长的情景。轻量级锁能够提升程序性能的依据是“对绝大部分的锁,在整个同步周期内都不存在竞争”。轻量级锁加锁流程如下图所示。

 

 2.3 重量级锁

当轻量级锁无法满足需求,多个线程仍然竞争同一个锁时,锁会升级为重量级锁。在这种情况下,线程将阻塞,直到获取锁。

2.4 各种锁对比

参考:
链接:https://juejin.cn/post/7292955463955906560

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1138174.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构 C语言 2.1 线性表抽象数据类型 2.2 小议顺序表

一、线性表抽象数据类型 线性表的定义 定义:零个或多个数据元素的有限序列 线性表的特点: 1.它是一个序列 数据元素之间是有序的 数据元素之间是一对一的关系 2.有限性 线性表的数据元素个数是有限的 注意:零个数据元素的有限序列又…

NewStarCTF2023week4-依旧是空白(snow隐写)

打开附件的空白图片,CRC报错,很可能是高度被修改 爆出图片正确的宽度和高度并修复 打开看到密码 password: s00_b4by_f0r_y0u 另一个文件是空白的txt文档,大致看了一下像是不可见字符,尝试 white_space,发现不是&…

Uservue 中 keep-alive 组件的作用

目录 前言 用法 代码 理解 keep-alive 是 Vue.js 中一个内置的组件,它能够将不活动的组件实例保存在内存中,防止其被销毁,以便在后续需要时能够快速重新渲染。这个功能在一些需要频繁切换但不希望每次都重新渲染的场景中非常有用&#xf…

详解预处理(2)

目录 #undef 命令行定义 条件编译 NO1. NO2.多个分支的条件编译 NO3.判断是否被定义 NO4.嵌套指令 文件包含 头文件被包含的方式 本地文件包含 库文件包含 嵌套文件包含 其他预处理指令 今天接着继续讲解预处理的点,前面已经深入学习了#define。 #unde…

基于Springboot 游戏娱乐信息平台-计算机毕设 附源码 04691

Springboot 游戏娱乐信息平台 目 录 摘要 1 绪论 1.1研究内容 1.2国内外研究慨况 1.3研究方法 1.4论文结构与章节安排 2 游戏娱乐信息平台系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性…

EvilAppleJuice(邪恶苹果汁)-ESP32C3项目(iphone疯狂弹窗)

原作者作品页: ckcr4lyf/EvilAppleJuice-ESP32: Spam Apple Proximity Messages via an ESP32 (github.com) 代码优化一下,增加呼吸灯效果方便知道设备运行情况,我是用arduino烧录 仅作交流学习使用,请勿在公开场合滥用 运行效果…

黑豹程序员-Python入门-for循环

文章目录 1、for循环语法2、巩固案例:长安三万里你记得的三位诗人?实现步骤:第一步:新建一个列表,存储诗人姓名第二步:列表用[]表示,元素之间用逗号,分隔第三步:用列表[索引]的方法将…

莫名其妙el-table不显示问题

完全复制element-ui中table代码,发现表格仍然不显示,看别人都说让降低版本,可我不想降低啊,不然其他组件有可能用不了,后来发现可以通过配置vite.config.js alias: {: path.resolve(__dirname, src),vue: vue/dist/vue…

【Docker】Python Flask + Redis 练习

一、构建flask镜像 1.准备文件 创建app.py,内容如下 from flask import Flask from redis import Redis app Flask(__name__) redis Redis(hostos.environ.get(REDIS_HOST,127.0.0.1),port6379)app.route(/) def hello():redis.incr(hits)return f"Hello Container W…

nexus5x 刷机root

刷机 进入fastboot模式 adb reboot bootloader 或者开机 音量减 解锁bootloader fastboot oem unlock 刷入rom包 下载 Nexus 和 Pixel 设备的出厂映像 | Google Play services | Google for Developers 选一个合适的ROM包下载到电脑的某个位置,然后unzip解…

国家网信办发布第十三批境内区块链信息服务备案编号

2019年2月15日《区块链信息服务管理规定》(以下简称《管理规定》)正式实施以来,国家互联网信息办公室依法依规组织开展备案审核工作,已发布2批次共506个境内区块链信息服务名称及备案编号,近日正式发布第三批共224个境…

剪映怎么合并两个视频?几个步骤轻松搞定!

合并两个视频可以方便我们管理、节省存储空间、提高处理效率、满足特定要求或实现特定效果等目的。而剪映作为我们常用的视频处理软件,如何利用其合并两个视频呢?一起来看看吧~ 方法一:使用剪映专业版 1、运行剪映,主…

关于maven项目中依赖无法下载的解决方案

场景描述 在下载selenium的依赖时,虽然相依的jar包已经存在,但是在idea中依然报红 解决方案 在jar无法正常下载时可以尝试使用——找到下载的文件夹,删除整个文件夹后重新通过链接下载 过程演示 C:\Users\lenovo\.m2 所有依赖的jar包都在这…

errno变量和显示错误信息

一、errno Linux很多函数发生错误,只会返回-1。所以,我们只知道函数发生了错误,却不知道具体发生了什么错误。 因此Linux 系统下对常见的错误做了一个编号,每一个编号都代表着每一种不同的错误类型。 发生错误时,对…

CTF-Crypto学习记录-第三天 MD5加密算法(信息摘要算法)“ “

文章目录 0x1 MD5 基本介绍0x2 MD5 加密特点0x3 MD5 加密原理步骤0x01 对明文数据进行信息填充0x02 设置初始变量0x03 加密运算过程加密运算流程图&#xff1a;四个非线性函数&#xff1a;Mj表示消息的第j个子分组&#xff08;从0到15&#xff09;&#xff0c;<<&#xf…

Python web开发中的单元测试自动化技巧!

Python作为一种广泛使用的编程语言&#xff0c;在web开发中也扮演着重要的角色。在进行web开发时&#xff0c;单元测试是一个不可或缺的环节。单元测试可以确保代码的正确性&#xff0c;并且能够在开发过程中快速发现问题&#xff0c;有助于提高代码质量和开发效率。 在Python…

非计算机小白成功转型Python教学分析师,月薪2W后,我的学习经验总结!

最近1年的主要学习时间&#xff0c;都投资到了python据分析和数据挖掘上面来了&#xff0c;虽然经验并不是十分丰富&#xff0c;但希望也能把自己的经验分享下&#xff0c;最近也好多朋友给我留言&#xff0c;和我聊天&#xff0c;问我python该如何学习&#xff0c;才能少走弯路…

桉木红面模板批发915*1830mm规格建筑木胶板

我们很自豪地介绍我们的产品&#xff1a;桉木红面建筑模板。作为一家专业的建筑木胶板生产批发商&#xff0c;我们提供高质量的915*1830*15mm规格的桉木红面板&#xff0c;为您的建筑项目提供卓越的解决方案。 桉木红面板是由优质的桉木原料制成&#xff0c;经过精细的加工和处…

论文分享——北邮:基于学习解纠缠因果子结构的图神经网络去偏

作者 &#xff1a;范少华 研究方向 &#xff1a;图神经网络 论文标题 &#xff1a;基于学习解纠缠因果子结构的图神经网络去偏 论文链接 &#xff1a;https://arxiv.org/pdf/2209.14107.pdf        https://doi.org/10.48550/arXiv.2209.14107 大多数图神经网络(GNNs)通…

基于YOLOv8模型的烟雾目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOv8模型的烟雾目标检测系统可用于日常生活中检测与定位烟雾目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法训练数据集…