一篇终结synchronized

news2024/11/23 17:28:56

一:基本原理

Java对象在内存中由两部分组成 : 1 是成员变量 2 是对象头,以32位虚拟机介绍:此时对象头是64位,即8字节
其中32个字节代表 mark word 另外32个字节代表klass word分别是什么意思呢?

1 klass word 代表对象的类型,即student、teacher这种
2 mark word 中,hashcode 占 25位,Age分代年龄 4位,Biased_lock代表是否是偏向锁,最后两位代表加锁状态

多线程访问三种情况
1 单线程访问
2 多线程交替访问
3 多线程竞争激烈
锁升级主要依赖存在Java对象中的Mark Word中的锁标识位和释放偏向锁标识位
无锁001
偏向锁101 MarkWord 存储的是偏向的线程ID
轻量锁00 MarkWord 存储的是线程栈Lock Record指针
重量锁10 MarkWord 存储的是指向堆中monitor对象的指针

二:锁升级之偏向锁

缺点:每次发生锁重入时,每次重入都需要cas检查
例如 方法1 调用方法2 方法2调用方法3,都是同一把锁,可以成功,但是每次都会新产生一个锁记录对象,和对象头交换,虽然交换失败,但是知道这个锁是自己加的,所以还是会拿到锁,这样每次都进行cas操作依然有性能损耗

有没有办法避免这种损耗呢?
就是偏向锁,只有第一次使用CAS将线程ID设置到对象(threadId 替换 markword),之后发现这个线程id是自己的就表示没有竞争,不用重新CAS,等于说这把锁是这个线程专用的了

三:锁升级之轻量锁

多线程访问时间错开,没有竞争,可以用轻量锁优化,语法依然是synchronized,使用时优先使用轻量锁,加锁失败,或竞争激烈才会用重量锁

基本原理

当线程a调用一个方法时,会产生一个锁记录对象
锁记录对象包含两部分{
1 对象指针,记录加锁对象的地址
2 存储将来加锁对象的mark word
}
如下图,左为锁记录对象,右为锁对象
在这里插入图片描述
锁记录对象会将对象指针与锁对象的mark word交换,这是一个CAS操作,此时,锁对象的mark word 中不再是之前提到的hashcode等信息,而是锁记录地址

四:锁膨胀

轻量级锁竞争失败,进入锁膨胀,升级为重量级锁,如果尝试加轻量锁失败,代表已经有其他线程加了轻量锁(有竞争),这时需要锁膨胀,将轻量锁升级为重量锁

例如现在thread1已经加了锁,现在来了一个thread2,想用轻量锁方式加锁,就想把自己的对象指针与markword交换,此时交换失败,因为此时后两位是00,不再是无锁状态

失败后进入锁膨胀

 1 为object对象申请Monitor锁,让Object指向重量级锁地址
 2 自己进入Monitor的EntryList bloked
 3 markword后两位变成10
 4 thread1 退出同步块解锁时,使用cas将mark word 的值恢复给对象头
 5 失败这时会进入重量级解锁流程,即按照monitor地址找到monitor对象,设置owner为null,唤醒
EntryList 的bloked线程

自旋优化:

一次失败后不立即进入阻塞,而是再尝试几次,在尝试的过程中
如果持有锁的线程退出了同步块,当前线程就可以避免阻塞

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

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

相关文章

文心一言 VS chatgpt (12)-- 算法导论3.1 6~7题

六、证明:一个算法的运行时间为θ(g(n))当且仅当其最坏情况运行时间为O(g(n)),且其最好情况运行时间为Ω(g(n)) 。 文心一言: chatgpt: 要证明「一个算法的运行时间为θ(g(n))当且仅当其最坏情况运行时间为O(g(n)),且…

LeetCode213 打家劫舍 II 动态规划法

题目地址 https://leetcode.cn/problems/house-robber-ii/ 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装…

【Hive实战】Windows下 IDEA DEBUG hiveMetastore hive2.3.9

Windows下 IDEA DEBUG hiveMetastore hive2.3.9 环境准备 编译好hive2.3.9源码,参考文档编译hive2.3.9源码准备好Mysql库,并手动创建schema,相关sql文件:hive-schema-2.3.0.mysql.sql和hive-txn-schema-2.3.0.mysql.sql。 启动…

SpringCloud --- Gateway服务网关

一、简介 Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。 二、为…

QT实现固高运动控制卡示波器

目录 一、固高示波器 二、基于QCustomPlot实现示波器 三、完整源码 一、固高示波器 固高运动控制卡自带的软件有一个示波器功能,可以实时显示速度的波形,可辅助分析电机的运行状态。但是我们基于sdk开发了自己的软件,无法再使用该功能&…

深度学习技巧应用8-各种数据类型的加载与处理,并输入神经网络进行训练

大家好,我是微学AI,今天给大家介绍一下深度学习技巧应用8-各种数据类型的加载与处理,并输入神经网络进行训练。在模型训练中,大家往往对各种的数据类型比较难下手,对于非结构化数据已经复杂的数据的要进行特殊处理&…

听我一句劝,别去外包,干了三年,废了....

先说一下自己的情况,大专生,18年通过校招进入湖南某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

2.黑马SpringbBoot运维篇笔记自己修改

SpringBoot运维实用篇 ​ 基础篇发布以后,看到了很多小伙伴在网上的留言,也帮助超过100位小伙伴解决了一些遇到的问题,并且已经发现了部分问题具有典型性,预计将有些问题在后面篇章的合适位置添加到本套课程中,作为解…

[社区图书馆】《PyTorch高级机器学习实战》书评

《PyTorch高级机器学习实战》是一本非常实用的机器学习书籍,作者为阿里云智能首席AI专家赵健。这本书的目标读者是具有一定Python编程基础并对深度学习有兴趣的开发者和研究者。 在书中,作者从最基础的线性回归、逻辑回归、卷积神经网络(CNN…

前端食堂技术周刊第 80 期:Vite 4.3、Node.js 20、TS 5.1 Beta、Windi CSS 即将落幕

美味值:🌟🌟🌟🌟🌟 口味:东坡肉 食堂技术周刊仓库地址:https://github.com/Geekhyt/weekly 本期摘要 Vite 4.3Node.js 20TypeScript 5.1 BetaWindi CSS 即将落幕Pretty TypeScri…

springboot项目的jar文件以打包成docker镜像的方式部署

清单: 安装有docker的Linuxspringboot打包的jar文件(该项目只有一个返回"hello world"接口) Linux的IP地址:192.168.221.129 springboot项目的接口: 1、上传jar文件至Linux 我上传的位置为:/…

4.2——派生类的构造函数和析构函数

派生类继承了基类的成员,实现了原有代码的重用,但是基类的构造函数和析构函数不能被继承,在派生类中,如果对派生类新增的成员进行初始化,就需要加入派生类的构造函数。与此同时,对所有从基类继承下来的成员…

SpringMVC-学习修改尚硅谷最新教程笔记

三、SpringMVC 1、SpringMVC简介 1.1、什么是MVC MVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分 M:Model,模型层,指工程中的JavaBean,作用是处理数据 JavaBean分为两类: **一类称为实…

【JAVA-模块五 数组】

JAVA-模块五 数组 一、数组(一维)1.1数组是什么?1.2java中数组静态初始化:(存)两种定义格式:数组初始化格式:静态初始化后,打印数组名: 1.3 数组元素访问&…

win11 环境下streamlit使用pycharm debug

目录 1. pycharm中配置run 脚本2. streamlit3. 开始debug调试 1. pycharm中配置run 脚本 (一)点击 Edit Configurations,按图操作. 2. streamlit 1.streamlit 安装在 anaconda 的 base 环境(随意哈,安装哪里都可以&#xff0c…

Zookeeper 面试题总结

Zookeeper 1、工作中 Zookeeper 有什么用途吗2、zookeeper 数据模型是什么样的3、那你知道 znode 有几种类型呢4、你知道 znode 节点里面存储什么吗5、每个节点数据最大不能超过多少呢6、你知道 znode 节点上监听机制嘛7、那你讲下 Zookeeper 特性吧8、你刚提到顺序一致性&…

LRU缓存淘汰策略——面试高频

⭐️前言⭐️ 本文主要介绍在面试中常见的高频手撕算法题目,LRU算法, 🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁 🍉博主将持续更新学习记录收获,友友们有任何问题可以在评论区…

LEVIR-CD遥感建筑变化检测数据集

LEVIR-CD是一个新的大规模遥感二元变化检测数据集,它将有助于开发新的基于深度学习的遥感图像变化检测算法。 下载地址:https://justchenhao.github.io/LEVIR/ 历史消息 20230311:我们为LEVIR_CD中的每个样本补充了地理空间信息(例如&#…

实例分割算法BlendMask

实例分割算法BlendMask 论文地址:https://arxiv.org/abs/2001.00309 github代码:https://github.com/aim-uofa/AdelaiDet 我的个人空间:我的个人空间 密集实例分割 ​ 密集实例分割主要分为自上而下top-down与自下而上bottom-up两类方法…

Node.js代码实例:简单Web服务端

文章目录 前言代码仓库为什么要写一份Node.js简单Web服务端的代码实例?内容目录结构代码server.jsindex.htmlindex.cssindex.jsvalue.html 结果总结参考资料作者的话 前言 Node.js代码实例:简单Web服务端。 代码仓库 yezhening/Programming-examples: …