synchronized 底层原理

news2024/11/28 0:55:13

synchronized 关键字的底层原理

jdk5 之前 synchronized 是重量级锁,但是jdk6 之后会有一个锁升级的过程

在这里插入图片描述
在这里插入图片描述

Monitor实现的锁属于重量级锁,你了解过锁升级吗?

Java中的synchronized有偏向锁、轻量级锁、重量级锁三种形式,分别对应了锁只被一个线程持有、竞争较不激烈的情况、竞争激烈的情况三种情况。

偏向锁
轻量级锁在没有竞争时(就自己这个线程),每次重入仍然需要执行CAS操作。
只有第一次使用CAS将线程ID设置到对象的 Mark Word头,之后发现这个线程ID是自己的就表示没有竞争,不用重新CAS。以后只要不发生竞争,这个对象就归该线程所有

在这里插入图片描述

适用于单线程适用的情况,在不存在锁竞争的时候进入同步方法/代码块则使用偏向锁。 比如我们在使用StringBuffer中的很多带synchronized的方法,其实大多数时候都不会存在锁竞争的情况就使用的是偏向锁,在第一次获得锁时,会有一个CAS操作,之后该线程再获取锁,只需要判断mark word中是否是自己的线程id即可,而不是开销相对较大的CAS命令

轻量级锁
在很多的情况下,在Java程序运行时,同步块中的代码都是不存在竞争的,不同的线程交替的执行同步块中的代码。这种情况下,用重量级锁是没必要的。因此JVM引入了轻量级锁的概念。

加锁流程
1.在线程栈中创建一个Lock Record,将其obj字段指向锁对象。
2.通过CAS指令将Lock Record的地址存储在对象头的mark word中,如果对象处于无锁状态则修改成功,代表该线程获得了轻量级锁。
3.如果是当前线程已经持有该锁了,代表这是一次锁重入。设置Lock Record第一部分为null,起到了一个重入计数器的作用。
4.如果CAS修改失败,说明发生了竞争,需要膨胀为重量级锁。

解锁过程
1.遍历线程栈,找到所有obj字段等于当前锁对象的Lock Record。
2.如果Lock Record的Mark Word为null,代表这是一次重入,将obj设置为null后continue。
3.如果Lock Record的 Mark Word不为null,则利用CAS指令将对象头的mark word恢复成为无锁状态。如果失败则膨胀为重量级锁。

在这里插入图片描述

适用于竞争较不激烈的情况,存在竞争时升级为轻量级锁,轻量级锁采用的是自旋锁(CAS),如果同步方法/代码块执行时间很短的话,采用轻量级锁虽然会占用cpu资源但是相对比使用重量级锁还是更高效。

重量级锁

Synchronized 底层是由monitor实现的,monitor是jvm级别的对象(C++实现),线程获得锁需要使用对象(锁)关联monitor,采用互斥的方式让同一时刻至多只有一个线程能持有对象锁,而在monitor内部有三个属性,分别是owner、entrylist、waitset,其中owner是关联的获得锁的线程,并且只能关联一个线程;entrylist关联的是处于阻塞状态的线程; waitset 关联的是处于 waiting 状态的线程

在这里插入图片描述

Monitor实现的锁属于重量级锁,里面涉及到了用户态和内核态的切换、进程的上下文切换,成本较高,性能比较低。

只有重量级锁才会关联Monitor,而对象是怎么关联上的Monitor的
在这里插入图片描述

重量级锁:适用于竞争激烈的情况,如果同步方法/代码块执行时间很长(这种情况自旋的次数就会变多,增加系统的消耗),那么使用轻量级锁自旋带来的性能消耗就比使用重量级锁更严重,这时候就需要升级为重量级锁。

默认情况下,JVM中自旋的最大次数为10(可通过"-XX: PreBlockSpin"参数进行修改),如果在这个次数后还未获得锁,则会升级为重量级锁。所以,如果我们希望减少轻量级锁向重量级锁的升级,可以适当增加自旋次数,例如将其设置为20-50。但是要注意,自旋次数越多,对CPU资源的消耗就越高。因此,需要在保证性能的前提下,根据具体的应用场景和硬件环境进行适当调整。

JVM 中,synchronized 锁只能按照偏向锁、轻量级锁、重量级锁的顺序逐渐升级(也有把这个称为锁膨胀的过程),不允许降级。

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

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

相关文章

Apache Zeppelin系列教程第六篇——Zengine调用Interpreter原理分析

Apache Zeppelin系列教程第五篇——Interpreter原理分析_诸葛子房_的博客-CSDN博客 Apache Zeppelin系列教程第四篇——JDBCInterpreter原理分析_诸葛子房_的博客-CSDN博客 前文介绍jdbc interpreter和interpreter模块交互代码,本篇文章主要分析Zengine调用Interp…

智能的本质人工智能与机器人领域的64个大问题阅读笔记(三)

目录 机器智能提高到人类的水平或者人类智能下降到机器的水平,都可以到达图灵点。 或许图灵测试是一个自我实现的预言:我们(声称)在打造“聪明”机器的同时,我们也在把人变笨。 不长脑的机器和不思考的人没什么两样&…

工作利器:三种简单方法将PPT转换成PDF

PDF是一种常用的文件格式,适合数据传输和阅读。在工作中,有时我们需要将PPT文件转换为PDF格式以方便使用。下面是几种将PPT转换为PDF的方法,其中方法二将修改为使用记灵在线工具进行转换。 方法一:直接将文件导出为PPT 一般来说…

OpenHarmony3.1安全子系统-签名系统分析

介绍 应用签名系统主要负责鸿蒙hap应用包的签名完整性校验,以及应用来源识别等功能。 子系统间接口: 应用完整性校验模块给其他模块提供的接口;完整性校验: 通过验签,保障应用包完整性,防篡改;…

postman接口自动化测试

Postman除了前面介绍的一些功能,还有其他一些小功能在日常接口测试或许用得上。今天,我们就来盘点一下,如下所示: 1.数据驱动 想要批量执行接口用例,我们一般会将对应的接口用例放在同一个Collection中,然…

上周,又劝退了10几个...

最近看了很多简历,很多候选人年限不小,但是做的都是一些非常传统的项目,想着也不能通过简历就直接否定一个人,何况现在大环境越来 越难,大家找工作也不容易,于是就打算见一见。 在沟通中发现,由…

chatgpt赋能Python-openpyxl_批注

Openpyxl 批注简介 Openpyxl 是一个用于操作 Microsoft Excel 文件的 Python 库,它提供了许多方便的功能来读取、写入和修改 Excel 文件。其中一个功能是批注,可以在单元格中添加注释或提醒。 Openpyxl 批注的具体用途 Openpyxl 批注在 Excel 工作表中…

应届毕业生第一份C++程序员工作看重什么?我聊聊自己的看法

大家知道应届毕业生的第一份工C程序员工作看重什么,我相信那位同学可能他那个想去做的时候就说啊,因为第二家公司是世界杯公司吗,是单休哈对吧,而且待遇没有另一家高。我相信我们大部分人其实都看中一个,是累不累啊&am…

(浙大陈越版)数据结构 第三章 树(上) 3.1 树和树的表示

目录 3.1.1 引子(顺序查找) 什么是树 查找 3.1.2 引子 二分查找例子(BinarySearch) 二分查找 3.1.3 引子 二分查找实现 二分查找代码 二分查找的启示 3.1.4 树的定义 一些基本术语: 3.1.5 树的表示 3.1.1 引子(顺序查找…

学习Se-net和Sk-net 附网络简单代码(pytorch)

(一)Se-net的原理和思路     Se-net严格来说是一个小结构,它可以直接插入已有的网络结构中,帮助原有结构获得更好的效果,如插入Resnet网络中。 Se-net的整个流程如下:     (1&#xf…

chatgpt赋能Python-opencv_python打开摄像头

OpenCV Python打开摄像头:一种简单的图像处理方式 OpenCV是一种常用的图像处理库,可以用Python编程轻松进行图像和视频处理。其中,打开摄像头也是OpenCV中常用的一种方法。在这篇文章中,我们将介绍OpenCV Python打开摄像头的原理…

chatgpt赋能Python-numpy开根

NumPy开根 在科学计算中,开根运算是一个经常需要进行的操作,它非常有用,可以用来求解方程、计算距离或者简单地将数据压缩成更容易理解的形式等。NumPy是一个强大的库,被广泛地用于Python编程中,它提供了用于开根的特…

chatgpt赋能Python-mofan_python

Mofan Python:一个优秀的入门编程网站 介绍 Mofan Python 是一个致力于帮助人们快速入门 Python 编程的网站。该网站提供了各种编程资源,包括 Python 相关的教程、实例、项目,以及机器学习和深度学习课程等。它的特点在于提供了详细的代码解…

华为OD机试真题 Java 实现【投篮大赛】【2023Q1 100分】

一、题目描述 你现在是一场采用特殊赛制投篮大赛的记录员。 这场比赛由若于回合组成,过去几回合的得分可能会影响以后几回合的得分,比赛开始时,记录是空白的。 你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录…

FastDDS安全机制1 - 安全配置

背景 OMG组织对于DDS的安全机制有着对应的定义,其定义在DDS-SECURITY文档中。 这其中主要包含了对应的身份认证、访问控制、通信加密和审计相关的插件。 资料来源:DDS-SECURITY 其实也主要保护了通信过程中的相关安全风险。 资料来源:DDS-S…

轻松保护文档安全:三种实用的PDF加密方法

在我们的日常工作中,经常会使用到PDF格式的文件。为了保护版权和隐私,有时候我们需要对文档进行加密处理。那么,如何对PDF进行加密呢?今天我将为大家介绍几种方法,其中包括记灵在线工具、迅捷PDF编辑器和Speedpdf。 方…

Debian11之 RKE2 部署 K8S 集群

官方地址 资源列表 主机IP主机名称主机角色软件192.168.111.50server1主节点1API Server、controller-manager 和 scheduler192.168.111.51server2主节点2API Server、controller-manager 和 scheduler192.168.111.52server3主节点3API Server、controller-manager 和 schedu…

SocketTools crack所有安全连接的默认安全协议

SocketTools crack所有安全连接的默认安全协议 在所有HTTP客户端组件中添加了对HTTP/2.0协议的支持。 更新了TLS 1.2(及更高版本)和SSH 2.0的安全选项,以使用Microsoft Windows 11和Windows Server 2022中提供的密码套件。较旧、安全性较低的密码套件已被弃用&#…

JavaScript 基础 DOM (二)

事件流 事件流是对事件执行过程的描述 事件捕获 从DOM的根元素开始去执行对应的事件 (从外到里) 事件冒泡 当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒 泡 addEventListener 第3个参数决定了事件是在捕获阶…

(数据结构)栈的实现——再一次保姆级教学

目录 1. 栈 ​编辑 1.2 栈的实现 2. 代码的实现 2.1 初始化栈和销毁栈 2.2栈顶元素的插入 2.3栈顶元素的删除 栈元素删除 2.4栈顶元素的获取和栈元素的个数 1. 栈 1.1 栈的概念和结构 栈(Stack)是一种线性存储结构,它具有如下特点: &#xff0…