Synchronized与锁升级

一:java对象内存布局

对象在堆内存的存储布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data) 和对齐填充

二:对象在堆内存中的存储布局

1:对象头 (在64位系统中,Mark Word占了8个字节,类型指针占了8个字节,一共是16个字节)
对象标记(Mark Word):默认存储对象的HashCode、分代年龄和锁标志等信息。
类元信息:对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象哪个类的实例
在这里插入图片描述
2:实例数据
存放类的属性(Field)数据信息,包括父类的属性信息
3:对齐填充
保证8个字节的倍数

在这里插入图片描述

三:Sychronized的锁升级

Synchronized用的锁是存在Java对象头里的MarkWord中,锁升级功能主要依赖MarkWord中锁标志位和释放偏向锁标志位
无锁:
偏向锁:MarkWord存储的是偏向的线程ID
轻量锁:MarkWord存储的是指向线程栈中Lock Record的指针
重量锁:MarkWord存储的是指向堆中的monitor对象(系统互斥量指针)
在这里插入图片描述

四:无锁

在这里插入图片描述

五:偏向锁

1:偏向锁的持有?
单线程竞争,当线程A第一次竞争到锁时,通过修改MarkWord中的偏向线程ID、偏向模式。如果不存在其他线程竞争,那么持有偏向锁的线程将永远不需要进行同步。

2:偏向锁的撤销?
当有另外一个线程逐步来竞争锁的时候,就不能再使用偏向锁了,要升级为轻量级锁,竞争线程尝试CAS更新对象头失败,同时检查持有偏向锁的线程是否还在执行:
(1)第一个线程正在执行Synchronized方法(处于同步块),它还没有执行完,其他线程来抢夺,该偏向锁会被取消掉并出现锁升级,此时轻量级锁由原来持有偏向锁的线程持有,继续执行同步代码块,而正在竞争的线程会自动进入自旋等待获得该轻量级锁
(2)第一个线程执行完Synchronized(退出同步块),则将对象头设置为无所状态并撤销偏向锁,重新偏向。

3:案例说明

public class SynchronizedUpDemo {public static void main(String[] args) {/*** 这里偏向锁在JDK6以上默认开启,开启后程序启动几秒后才会被激活,可以通过JVM参数来关闭延迟 -XX:BiasedLockingStartupDelay=0*/try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }o = new Object();synchronized (o) {System.out.println(ClassLayout.parseInstance(o).toPrintable());}}
}

在这里插入图片描述

六:轻量级锁

1:什么是轻量级锁?
多线程竞争,但是任意时候最多只有一个线程竞争,即不存在锁竞争太激烈的情况,也就没有线程阻塞。

在这里插入图片描述
2:轻量级锁升级到 重量级锁
自旋一定程度和次数(Java8 之后是自适应自旋锁------意味着自旋的次数不是固定不变的
(1)线程如果自旋成功了,那下次自旋的最大次数会增加,因为JVM认为既然上次成功了,那么这一次也大概率会成功
(2)如果很少会自选成功,那么下次会减少自旋的次数甚至不自旋,避免CPU空转

七:重量级锁

1:有大量线程参与锁的竞争,冲突性很高
2:重量级锁原理
在这里插入图片描述
3:代码演示
在这里插入图片描述

八:常见面试题

1:轻量锁和偏向锁的区别:
(1)争夺轻量锁失败时,自旋尝试抢占锁
(2)轻量级锁每次退出同步块都需要释放锁,而偏向锁是在竞争发生时才释放锁,线程不会主动释放偏向锁
2:为什么每个对象都能作为一个锁?
java对象 是天生的Monitor,每一个对象都有成为Monitor的潜质,因为在Java设计中,每一个Java对象自打娘胎里出来就带一个看不见的锁,它叫内部锁或者Monitor锁
3:Monitror与java对象以及线程如何关联?

4:锁升级后,hashcode去哪儿了?
在这里插入图片描述
在这里插入图片描述
5:什么是锁消除?

/**/*** @Author:xiaoqi* @creat 2023/8/12 11:27* 锁消除* 从JIT角度看想相当于无视他,synchronized(o)不存在了* 这个锁对象并没有被共用扩散到其他线程使用* 极端的说就是根本没有加锁对象的底层机器码,消除了锁的使用*/
public class LockClearUpDemo {static Object object = new Object();public void m1() {//锁消除问题,JIT会无视它,synchronized(o)每次new出来的,都不存在了,非正常的Object o = new Object();synchronized (o) {System.out.println("-----------hello LockClearUpDemo" + "\t" + o.hashCode() + "\t" + object.hashCode());}}public static void main(String[] args) {LockClearUpDemo lockClearUpDemo = new LockClearUpDemo();for (int i = 0; i < 10; i++) {new Thread(() -> {lockClearUpDemo.m1();}, String.valueOf(i)).start();}}
}
/*** -----------hello LockClearUpDemo	229465744	57319765* -----------hello LockClearUpDemo	219013680	57319765* -----------hello LockClearUpDemo	1109337020	57319765* -----------hello LockClearUpDemo	94808467	57319765* -----------hello LockClearUpDemo	973369600	57319765* -----------hello LockClearUpDemo	64667370	57319765* -----------hello LockClearUpDemo	1201983305	57319765* -----------hello LockClearUpDemo	573110659	57319765* -----------hello LockClearUpDemo	1863380256	57319765* -----------hello LockClearUpDemo	1119787251	57319765*/

6:什么是锁粗化?

/*** @Author:xiaoqi* @creat 2023/8/12 12:27* 锁粗化* 假如方法中首尾相接,前后相邻的都是同一个锁对象,那JIT编译器会把这几个synchronized块合并为一个大块* 加粗加大范围,一次申请锁使用即可,避免次次的申请和释放锁,提高了性能*/
public class LockBigDemo {static Object objectLock = new Object();public static void main(String[] args) {new Thread(() -> {synchronized (objectLock) {System.out.println("111111111111");}synchronized (objectLock) {System.out.println("222222222222");}synchronized (objectLock) {System.out.println("333333333333");}synchronized (objectLock) {System.out.println("444444444444");}//底层JIT的锁粗化优化synchronized (objectLock) {System.out.println("111111111111");System.out.println("222222222222");System.out.println("333333333333");System.out.println("444444444444");}}, "t1").start();}
}

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

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

相关文章

基础课23——设计客服机器人

根据调查数据显示&#xff0c;使用纯机器人完全替代客服的情况并不常见&#xff0c;人机结合模式的使用更为普遍。在这两种模式中&#xff0c;不满意用户的占比都非常低&#xff0c;不到1%。然而&#xff0c;在满意用户方面&#xff0c;人机结合模式的用户满意度明显高于其他模…

Redis02-持久化策略

目录 RDB&#xff08;Redis DataBase Backup file&#xff09; RDB执行原理 AOF&#xff08;Append-Only File&#xff09; RDB和AOF对比 Redis支持多种持久化方式&#xff0c;以确保数据在内存中持久存储&#xff0c;以便在Redis服务器重启时数据不会丢失。Redis中持久化的…

Android Studio(列表视图ListView)

前言 前面在适配器章节&#xff0c;已经介绍了ListView的作用(干什么的)&#xff0c;这节将主要介绍如何去设计ListView页面视图。 思考 列表视图需要些什么&#xff1f; 1. 列表项容器&#xff08;装载各列表项的容器&#xff09;&#xff1a;<ListView/> 2. 列表项布局…

MySQL数据脱敏(Data masking plugin functions)

对于企业而言&#xff0c;数据脱敏可以在数据共享或测试时用于保护敏感数据&#xff08;如信用卡&#xff0c;社保卡&#xff0c;地址等&#xff09;。通过对敏感数据进行脱敏处理&#xff0c;组织可以最大限度地降低数据泄露和未经授权访问的风险&#xff0c;同时仍能够使用真…

AI技术再刷屏!明星集体“说”外语,有何风险?

近日&#xff0c;一段美国歌手泰勒斯威夫特“说”中文的短视频在网络刷屏&#xff0c;引发热议。 视频中&#xff0c;泰勒斯威夫特“说”着流利中文&#xff0c;音色和讲母语时的音色类似&#xff0c;甚至连口型都能对上。 类似的视频还有很多外国人“说”地道中文、很多中国…

figma-如何批量修改字体

一.选择字体 二.批量替换 编辑—>替换相同字体

UI设计工具都哪些常用的,推荐这5款

对于UI设计师来说&#xff0c;日常工作无非是围绕“需求分析”→设计实施→“开发交付”这三个环节来进行。 然而&#xff0c;在每个环节中&#xff0c;设计师使用的工具却完全不同。在这里&#xff0c;我收集整理了UI设计师在日常工作中常用的五种工具&#xff0c;希望能为新…

【ChatOCR】OCR+LLM定制化关键信息抽取(附开源大语言模型汇总整理)

目录 背景技术方案存在的问题及解决思路关键信息提取结果其他解决方案替换文心一言LangChain大型多模态模型&#xff08;Large Multimodal Model, LMM&#xff09; 开源大模型汇总LLaMA —— Meta 大语言模型Stanford Alpaca —— 指令调优的 LLaMA 模型Lit-LLaMA —— 基于 na…

数据结构线性表——单链表

前言&#xff1a;小伙伴们又见面啦&#xff0c;这篇文章我们来一起学习线性表的第二模块——单链表。 单链表的学习就要开始上强度啦&#xff0c;小伙伴们一定要努力&#xff0c;坚持&#xff01; 目录 一.什么是单链表 二.单链表与顺序表的区别 三.单链表的实现 1.单链表…

ClickHouse 学习之从高级到监控以及备份(二)

第 一 部分 高级篇 第 1 章 Explain 查看执行计划 在 clickhouse 20.6 版本之前要查看 SQL 语句的执行计划需要设置日志级别为 trace 才能可以看到&#xff0c;并且只能真正执行 sql&#xff0c;在执行日志里面查看。在 20.6 版本引入了原生的执行计划的语法。在 20.6.3 版本成…

【MongoDB】集群搭建实战 | 副本集 Replica-Set | 分片集群 Shard-Cluster | 安全认证

文章目录 MongoDB 集群架构副本集主节点选举原则搭建副本集主节点从节点仲裁节点 连接节点添加副本从节点添加仲裁者节点删除节点 副本集读写操作副本集中的方法 分片集群分片集群架构目标第一个副本集第二个副本集配置集初始化副本集路由集添加分片开启分片集合分片删除分片 安…

第23期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练 Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

Java 高效生成按指定间隔连续递增的列表(int,double)

简介 Java 按照指定间隔生成连续递增的List 列表&#xff08;引入Stream 类和流操作来提高效率&#xff09;&#xff1a; 1. 生成递增的List< Integer> Testpublic void test009(){int start 1;int interval 2;int count 10;List<Integer> list IntStream.ite…

【亚马逊云科技产品测评】活动征文|亚马逊云科技AWS之EC2详细测评

引言 &#xff08;授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道&#xff09; 在当前的数字化时代&#xff0c;云服务已…

算法题:203. 移除链表元素(递归法、设置虚拟头节点法等3种方法)Java实现创建链表与解析链表

1、算法思路 讲一下设置虚拟头节点的那个方法&#xff0c;设置一个新节点指向原来链表的头节点&#xff0c;这样我们就可以通过判断链表的当前节点的后继节点值是不是目标删除值&#xff0c;来判断是否删除这个后继节点了。如果不设置虚拟头节点&#xff0c;则需要将头节点和后…

【SpringSecurity】简介

SpringSecurity简介 Spring Security 的前身是Acegi Security&#xff0c;在被收纳为Spring 子项目后正式更名为Spring Security。Spring Security目前已经到了6.x&#xff0c;并且加入了原生OAuth2.0框架&#xff0c;支持更加现代化的密码加密方式。可以预见&#xff0c;在Ja…

HDFS速通之一文详解HDFS全部知识点

文章目录 HDFS介绍HDFS体系HDFS的Shell介绍HDFS的常见Shell操作 HDFS案例实操Java操作HDFS配置环境 HDFS的回收站HDFS的安全模式实战&#xff1a;定时上传数据至HDFSHDFS的高可用和高扩展HDFS的高可用(HA)HDFS的高扩展(Federation) HDFS介绍 HDFS是一个分布式的文件系统 假设…

oracle-sql语句执行过程

客户端输入sql语句。 sql语句通过网络到达数据库实例。 服务器进程(server process)接收到sql语句。 sql – 解析成执行计划&#xff0c;然后sql才能执行。 会将sql和sql的执行计划缓存到共享池中。解析: 会消耗很多资源。 从数据库找数据&#xff0c;先从buffer cache中找&a…

数组相关的面试OJ题

目录 1.移除元素 方法1【暴力求解】 方法2【双指针】 2.删除两个有序数组中的重复项 方法1【双指针】 3.合并两个有序数组 方法1【暴力求解】 方法2【开辟新数组】---选择较小的尾插 方法3【三指针】---选择较大的头插 4.有序数组的合并 方法1【三指针】 写一个算…

Git extension 中合并工具kdiff3乱码问题

打开kdiff3合并工具&#xff0c;setting->region settings 设置下面的编码格式为utf-8就可以啦&#xff01; 注意&#xff1a;需要在合并工具中设置编码格式&#xff0c; 在git 中配置编码格式没有效果