【Java 多线程】Synchronized

news2024/10/7 4:29:37

Synchronized

Synchronized 是Java的一个关键字,它能够将代码块或方法锁起来,是一种互斥锁,一次只能允许一个线程进入被锁住的代码块

  • 如果 Synchronized 修饰的是实例方法,则对应的锁是对象实例
  • 如果 Synchronized 修饰的是静态方法,对应的锁是当前类的 Class 实例
  • 如果 Synchronized 修饰的是代码块,对应的锁是传入 Synchronized 的对象实例

Synchronized 的原理

当 Synchronized 修饰的是方法的时候,通过反编译可以看到通过 ACC_SYNCHRONIZED来标识

当 Synchronized 修饰的是代码块的时候,通过反编译可以看到,是通过 monitorentermonitorexit 指令来控制加加锁和解锁的。

Monitor : 每个对象都会存在一个与之对应的 Monitor 对象,Monitor 对象中存储着当前持有锁的线程和等待加锁的线程队列

monitorentermonitorexit 指令分别会让锁计数器+1或者-1,每一个对象在同一时间只能与一个monitor 相关联,一个 monitor 在同一时间只能被一个线程获取

当某个线程想要获取与一个对象相关联的 monitor 锁的所有权的时候,会触发 monitorenter 指令,会有三种情况:

  • monitor 计数器为 0,没有线程获取该 monitor,所以直接将计数器+1即可,其他线程想要获取就要等待
  • 如果这个线程已经拿到了这个 monitor 锁的所有权,那么就是锁的重入,计数器+1即可
  • 这把锁已经被别的线程获取了,则会等待锁的释放

当某个线程去释放锁的时候,会触发monitorexit指令,对于释放 monitor 的所有权相对简单,只要将计数器 -1 即可,-1 后不为 0 则为重入了锁,当前线程还会持有锁,-1 后为 0 则释放了锁

JVM 中锁的优化

Jdk1.6 之前,Synchronized 的加锁是依赖底层操作系统的 Mutex 来实现的,需要在用户态和内核态之间进行切换,资源消耗很大,锁的性能相对比较低,所以在 jdk1.6 中对锁引入了很多优化,锁粗化、锁消除、轻量级锁、偏向锁、适应性自旋

  • 锁粗化:减少不必要的紧连在一起的unlock,lock 操作。将多个连续的锁扩展为一个更大范围的锁
  • 锁消除:通过逃逸分析,JVM 会判断在一段程序中的同步明显不会逃逸出去从而被其他线程访问到,那 JVM 就把他当做栈上数据对待,认为这些数据是线程独有的不需要加同步
  • 轻量级锁:一般情况下,程序中的大部分同步代码都处于无锁竞争状态,即单线程执行环境,在这种情况下,就可以避免调用操作系统的重量级锁,可以用简单的 CAS 来代替monitorentermonitorexit 指令。当存在竞争是,执行 CAS 失败的线程将调用操作系统互斥锁进入阻塞状态,当锁被释放的时候被唤醒
  • 偏向锁:为了在无锁竞争的环境下避免在锁获取的时候执行不必要的 CAS 指令
  • 适应性自旋:当线程在获取轻量级锁失败的时候,在进入操作系统互斥锁进行阻塞之前,会进行忙等待,然后尝试获取锁,尝试一定次数后仍然没有获取锁时,则调用与该 monitor 相关联的互斥锁进入阻塞等待

在 jdk 1.6 中 Synchronized 锁一共有四种状态:无锁、偏向锁、轻量级锁、重量级锁会随着竞争情况不断升级,升级过程不可逆

轻量级锁

在内存中,对象一般由三部分组成,分别是对象头、实际数据和对齐填充,重点在与对象头,对象头中有一个我们比较关注的部分,MarkWord,MarkWord 中记录了有关锁的信息包括锁标记位,是否为偏向锁等

轻量级的锁的加锁过程:

在线程执行同步块之前,JVM 会现在当前线程的栈帧中创建一个锁记录(Lock Record),用于存储锁对象目前的 MarkWord 拷贝

image-20240418154731659

如果对象没有被锁定,那么锁的标志位为 01,JVM 在执行当前线程时,会先在当前线程的栈帧中创建 LockRecord 用于存储对象的 MarkWord 的拷贝

然后虚拟机使用 CAS 操作将标记字段 MarkWord 拷贝到锁记录中,并将 MarkWord 更新为指向 LockRecord 的指针,如果更新成功了那么线程就拥有了该对象的锁,并且对象的 MarkWord 的锁标记位更新为 00 表示当前为轻量级锁状态

image-20240418155043857

如果更新操作失败,如果 MarkWord 中存在指向当前线程的栈帧的指针,那么就直接使用即可,如果不存在指向当前线程栈帧的指针,说明这个锁已经被其他线程抢占了,这个时候就要锁膨胀进入重量级锁了,并且当前线程会阻塞等待,此时锁标记位为 10,MarkWord 中存储着指向重量级锁的指针

轻量级锁解锁时,会使用原子 CAS 操作将 MarkWord 替换回对象头中,替换失败则表示存在竞争,升级为重量级锁

偏向锁

JVM 会认为只有某个线程会获取锁,在大多数环境下锁是不存在竞争的,而且总是由一个线程多次获取,所以这样多次获取锁再释放锁的开销是没有意义的,为了解决这个问题,在 jdk1.6 中,引入了偏向锁的概念。

当一个线程访问同步块的时候,会在对象头和栈帧中的锁记录中存储获取了该偏向锁的线程的 ID,以后线程在进入同步代码块之前不需要进行 CAS 操作来加锁和解锁,只需要简单判断对象头中是否存储着自己的线程 ID,也就是指向自己线程的偏向锁

锁升级的过程

image-20240419104031836

偏向锁状态下,线程要获取锁时,会在 MarkWord 中直接记录线程 ID,只要线程来执行代码了,会对比线程 ID 是否相等,相等直接获取锁,执行同步代码,不相等则尝试使用 CAS 修改 MarkWord 中的线程 ID ,如果修改成功则获取锁,修改不成功说明有竞争,因此会撤销偏向锁升级为轻量级锁

在轻量级锁状态下, 线程会在栈帧中创建 LockRecord 空间,用于存储锁对象的 MarkWord 的拷贝,在执行同步代码之前,尝试使用 CAS 修改 MarkWord 为指向 LockRecord 的指针,修改成功则获取锁,修改失败则会自旋,自旋一段时间没获取锁,则升级为重量级锁

在重量级锁的状态下,则依赖操作系统的 mutex 指令,需要用户态和内核态的切换,重量级锁用到 Monitor 对象,monitor 中存储着当前持有锁的线程和等待所释放的线程队列。

锁升级的过程是不可逆的

只有一个线程进入临界区,偏向锁

多个线程交替进入临界区,轻量级锁

多线程同时进入临界区,重量级锁

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

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

相关文章

SSL证书在HTTP与HTTPS中的角色差异是什么?

在互联网的广泛应用背景下,随着网络攻击和数据泄露事件频发,保障用户的数据安全已成为至关重要的议题。传统的HTTP协议在传输数据时不进行加密处理,导致数据在传输过程中暴露于潜在的窃听和篡改风险中,安全性薄弱。而通过引入SSL/…

Springboot+Vue项目-基于Java+MySQL的免税商品优选购物商城系统(附源码+演示视频+LW)

大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:Java毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计 &…

Linux的图形资源及指令

一、火车 1.切换到超级用户 su 2.下载资源 yum install -y sl 3.输入指令 sl,得到火车图形 如果没有得到该图形,就将2处改为yum install -y epel-release。 二、Linux的logo 1.在超级用户模式下下载资源 yum install -y linux_logo 2.输…

英语日常用语柯桥职场英语学习去哪里?专业语言培训推荐泓畅学校

“摸鱼”的英语表达 职场,总有些看似努力工作的同事,很可能是深藏不漏的“摸鱼圣手”。 但“摸鱼”的英文表达绝对不是“touch fish”这么简单!上班摸鱼,就是不好好干活、浪费时间,所以“loaf”这个单词有必要了解一下…

腾讯EdgeOne产品测评体验—更快更强更安全,安全我选EdgeOne

腾讯EdgeOne产品测评体验—更快更强更安全,安全我选EdgeOne 王婆的瓜可甜? 自 23 年 8 月份 EdgeOne 开放订阅套餐后,腾讯云用户使用 EdgeOne 来为自己网站进行加速和防护的站点数量,呈现爆发式增长趋势。 金融服务业受到的 Web…

AI智能边缘分析一体机,32T算力,可同时处理32路1080p高清视频

产品概述 XM-AIBOX-32智能边缘分析一体机是一款高性能、低功耗边缘计算产品。搭载BM1684X主芯片,INT8算力高达32TOPS,FP16/BF16算力高达16TFLOPS,FP32算力高达2TFLOPS,可同时处理32路高清视频,支持32路1080P高清视频硬…

LeetCode in Python 1338. Reduce Array Size to The Half (数组大小减半)

数组大小减半思路简单,主要是熟悉python中collections.Counter的用法,采用贪心策略即可。 示例: 图1 数组大小减半输入输出示例 代码: class Solution:def minSetSize(self, arr):count Counter(arr)n, ans 0, 0for i, valu…

LTD270次升级 | 订单支持部分退款 • 主动退款 • 商城可限制收货地区 • 官微中心App权限获取更透明

1、 改进退款功能,支持部分商品退款或只退运费; 2、 新增收货地区设置功能,可限制收货地区; 3、 自定义内容类型可使用历史参数快捷输入; 4、 Android版官微中心App系统权限授权流程优化; 5、 已知问题…

7-26 单词长度

题目链接&#xff1a;7-26 单词长度 一. 题目 1. 题目 2. 输入输出格式 3. 输入输出样例 4. 限制 二、代码 1. 代码实现 #include <stdio.h> #include <stdbool.h>void printLen(int len, bool printOnce) {if (len) {if (printOnce) {printf(" %d",…

Zabbix自定义模板、邮件报警、自动发现与注册、proxy代理、SNMP监控

目录 自定义监控内容 1.明确需要执行的 linux 命令 2.创建 zabbix 的监控项配置文件&#xff0c;用于自定义 key 3.在服务端验证新建的监控项 在 Web 页面创建自定义监控项模板 1.创建模板 2.创建应用集&#xff08;用于管理监控项的&#xff09; 3.创建监控项 4.创建…

SQL优化——访问路径(ACCESS PATH)

文章目录 1、常见访问路径1.1、TABLE ACCESS FULL1.2、TABLE ACCESS BY USER ROWID1.3、TABLE ACCESS BY ROWID RANGE1.4、TABLE ACCESS BY INDEX ROWID1.5、INDEX UNIQUE SCAN1.6、INDEX RANGE SCAN1.7、INDEX SKIP SCAN1.8、INDEX FULL SCAN1.9、INDEX FAST FULL SCAN1.10、I…

Sentinel + Nacos流控规则持久化配置

json参数对映sentinel 规则面板 [{"controlBehavior": 0,"count": 2,"grade": 1,"limitApp": "default","resource": "flow","strategy": 0} ] 第二步&#xff0c;告诉订单服务读取配置&…

RedHat9 KVM虚拟技术

以下有使用RedHat9单独的虚拟机也有使用RHEL9学员练习机和RHEL7学员练习机 KVM虚拟技术介绍 Linux的KVM(Kernel-based Virtual Machine)虚拟技术是一种基于Linux内核的虚拟化解决方案。它允许在单个物理服务器上创建和运行多个隔离的虚拟机,每个虚拟机都有自己的操作系统和…

算法题解记录17+++完全平方数

这是楼主第一次不靠题解&#xff0c;挑战动态规划的中等题目&#xff0c;虽然最终结果只超过了5%的人&#xff0c;不过我也很满意了。 本题楼主首先采用朴素的递归型动态规划&#xff0c;接着优化算法&#xff0c;使用借助HashMap存储临时数据的递归型动态规划&#xff0c;几次…

攻防世界15:xff-referer

首先需要了解什么是xff--代理服务器&#xff0c;通过代理访问服务器&#xff0c;referer:HTTP REFERER 是hesder的一部分&#xff0c;当浏览器向web服务器发送请求的时候&#xff0c;一般会带上Referer,告诉服务器该网页是从哪个页面链接过来的&#xff0c;服务器因此可以获得一…

数据结构--顺序表(C语言版)

&#xff08;一&#xff09;.顺序表的概念及结构 首先&#xff0c;我们来了解一下什么是数据结构呢&#xff1f; 数据结构是顾明思义就是由数据结构。 常⻅的数值1、2、3、4.....、教务系统⾥保存的⽤⼾信息&#xff08;姓名、性别、年龄、学历等 等&#xff09;、⽹⻚⾥⾁眼…

基于SSM的列车订票管理系统(含源码+sql+视频导入教程+文档+PPT)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的列车订票管理系统3拥有两种角色&#xff1b;管理员、用户 管理员&#xff1a;用户管理、车票管理、购票指南管理、系统管理等 用户&#xff1a;发布帖子、登录注册、购票等 1.…

洲宇新作 成都越秀·天悦云萃,献给城市的作品

筑是生活的镜子”——贝聿铭 建筑&#xff0c;往往折射一个时代的审美 随着城市快速扩张时代正在逐渐走向结束&#xff0c;各城市发展回归主城中心&#xff0c;高价值的主城区域正在掀起新的时代。新时代高净值置业者从追求奢华与气派到回归住宅的本质与需求。首先产品不仅要满…

机器学习鸢尾花各种模型准确率对比

流程 获取数据集导入需要的包读取数据划分训练集和测试集调用各种模型比较准确率 获取数据集 链接&#xff1a;https://pan.baidu.com/s/1RzZyXsaiJB3e611itF466Q?pwdj484 提取码&#xff1a;j484 --来自百度网盘超级会员V1的分享导入需要的包 import pandas as pd impo…

C语言 | Leetcode C语言题解之第32题最长有效括号

题目&#xff1a; 题解&#xff1a; int longestValidParentheses(char* s) {int n strlen(s);int left 0, right 0, maxlength 0;for (int i 0; i < n; i) {if (s[i] () {left;} else {right;}if (left right) {maxlength fmax(maxlength, 2 * right);} else if (…