(四) 共享模型之管程【Monitor 概念】

news/2024/5/6 1:23:06/文章来源:https://blog.csdn.net/yirenyuan/article/details/128120823

一、Java 对象头(P75)

  

二、原理之 Monitor()

Monitor 被翻译为监视器管程

每个 Java 对象都可以关联一个 Monitor 对象,如果使用 synchronized 给对象上锁(重量级)之后,该对象头的 Mark Word 中就被设置指向 Monitor 对象的指针

(1)刚开始 Monitor 中 Owner 为 null。

(2)当 Thread-2 执行 synchronized(obj) 就会将 Monitor 的所有者 Owner 置为 Thread-2,Monitor 中只能有一个 Owner。

(3)在 Thread-2 上锁的过程中,如果 Thread-3,Thread-4,Thread-5 也来执行 synchronized(obj),就会进入 EntryList BLOCKER。

(4)Thread-2 执行完同步代码块的内容,然后唤醒 EntryList 中等待的线程来竞争锁,竞争是非公平的。

(5)图中 WaitSet 中的  Thread-0, Thread-1 是之前获得过锁的,当条件不满足加入 WAITING 状态的线程,后面涉及到 wait-notify 时会分析

注意:
(1)synchronized 必须是进入同一个对象的 monitor 才有上述的效果
(2)不加 synchronized 的对象不会关联监视器,不遵从以上规则

三、原理之 synchronized

 

四、小故事(方便理解 Monitor、轻量级锁、偏向锁)

故事角色
老王 - JVM
小南 - 线程
小女 - 线程
房间 - 对象
房间门上 - 防盗锁 - Monitor
房间门上 - 小南书包 - 轻量级锁
房间门上 - 刻上小南大名 - 偏向锁
批量重刻名 - 一个类的偏向锁撤销到达 20 阈值
不能刻名字 - 批量撤销该类对象的偏向锁,设置该类不可偏向

 

五、原理之 synchronized 进阶

1. 轻量级锁

轻量级锁的使用场景:如果一个对象虽然有多线程要加锁,但加锁的时间是错开的(也就是没有竞争),那么可以使用轻量级来优化。

轻量级锁对使用者是透明的,即语法仍然是 synchronized。

 

(1)创建锁记录(Lock Record)对象,每个线程都的栈帧都会包含一个锁记录的结构,内部可以存储锁定对象的 Mark Word

 

(2)让锁记录中 Object reference 指向锁对象,并尝试用 cas 替换 Object Mark Word,将 Mark Word 的值存入锁记录

如果 cas 替换成功,对象头中存储了 锁记录地址和状态 00 ,表示由该线程给对象加锁,这时图示如下

 如果 cas 失败,有两种情况

1️⃣如果是其它线程已经持有了该 Object 的轻量级锁,这时表明有竞争,进入锁膨胀过程

2️⃣如果是自己执行了 synchronized 锁重入,那么再添加一条 Lock Record 作为重入的计数

 

(3)当退出 synchronized 代码块(解锁时)如果有取值为 null 的锁记录,表示有重入,这时重置锁记录,表示重入计数减一

当退出 synchronized 代码块(解锁时)锁记录的值不为 null,这时使用 cas Mark Word 的值恢复给对象头

1️⃣成功,则解锁成功

2️⃣失败,说明轻量级锁进行了锁膨胀或已经升级为重量级锁,进入重量级锁解锁流程

2. 锁膨胀

如果在尝试加轻量级锁的过程中,CAS 操作无法成功,这时一种情况就是有其它线程为此对象加上了轻量级锁(有竞争),这时需要进行锁膨胀,将轻量级锁变为重量级锁

 

(1) Thread-1 进行轻量级加锁时,Thread-0 已经对该对象加了轻量级锁

 

(2)这时 Thread-1 加轻量级锁失败,进入锁膨胀流程

1️⃣即为 Object 对象申请 Monitor 锁,让 Object 指向重量级锁地址
2️⃣然后自己进入 Monitor Entry

 

(3)当 Thread-0 退出同步块解锁时,使用 cas Mark Word 的值恢复给对象头,失败。这时会进入重量级解锁流程,即按照 Monitor 地址找到 Monitor 对象,设置 Owner null,唤醒 EntryList BLOCKED 线程

3. 自旋优化

重量级锁竞争的时候,还可以使用自旋来进行优化,如果当前线程自旋成功(即这时候持锁线程已经退出了同步块,释放了锁),这时当前线程就可以避免阻塞。

(1)自旋会占用 CPU 时间,单核 CPU 自旋就是浪费,多核 CPU 自旋才能发挥优势。

(2)在 Java6 之后自旋锁是自适应的,比如对象刚刚的一次自旋操作成功过,那么认为这次自旋成功的可能性会高,就多自旋几次;反之,就少自旋甚至不自旋,总之,比较智能。

(3)Java7 之后不能控制是否开启自旋功能。

 4. 偏向锁

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

 

 

4.1 偏向状态

一个对象创建时:
(1)如果开启了偏向锁(默认开启),那么对象创建后,markword 值为 0x05 即最后 3 位为 101,这时它的 threadepochage 都为 0
(2)偏向锁是默认是延迟的,不会在程序启动时立即生效,如果想避免延迟,可以加 VM 参数 -XX:BiasedLockingStartupDelay=0 来禁用延迟
(3)如果没有开启偏向锁,那么对象创建后,markword 值为 0x01 即最后 3 位为 001,这时它的 hashcode、 age 都为 0,第一次用到 hashcode 时才会赋值

 

注意
处于偏向锁的对象解锁后,线程 id 仍存储于对象头中

4.2 撤销 - 调用对象 hashCode

调用了对象的 hashCode,但偏向锁的对象 MarkWord 中存储的是线程 id,如果调用 hashCode 会导致偏向锁被撤销。

1️⃣轻量级锁会在锁记录中记录 hashCode

2️⃣重量级锁会在 Monitor 中记录 hashCode

在调用 hashCode 后使用偏向锁,记得去掉【-XX:-UseBiasedLocking】

4.3 撤销 - 其它线程使用对象

当有其他线程使用偏向锁对象时,会将偏向锁升级为轻量级锁。

 

4.4 撤销 - 调用 wait/notify

4.5 批量重偏向

如果对象虽然被多个线程访问,但没有竞争,这时偏向了线程 T1 的对象仍有机会重新偏向 T2,重偏向会重置对象的 Thread ID。

当撤销偏向锁阈值超过 20 次后,jvm 会这样觉得,我是不是偏向错了呢,于是会在给这些对象加锁时重新偏向至加锁线程

4.6 批量撤销

当撤销偏向锁阈值超过 40 次后,jvm 会这样觉得,自己确实偏向错了,根本就不该偏向。于是这个类的所有对象都会变为不可偏向的,新建的对象也是不可偏向的。

4.7 锁消除

锁消除是发生在编译器级别的一种锁优化方式。有时候我们写的代码完全不需要加锁,却执行了加锁操作。通过编译器将其优化,将锁消除。

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

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

相关文章

基于改进萤火虫算法的图像分割的应用(Matlab代码实现)

🍒🍒🍒欢迎关注🌈🌈🌈 📝个人主页:我爱Matlab 👍点赞➕评论➕收藏 养成习惯(一键三连)🌻🌻🌻 🍌希…

【信管2.4】项目运行环境与项目经理

项目运行环境与项目经理加餐加餐来了哦,今天的内容在 《信息系统项目管理师教程》 这本教材里是没有的,而且在 PMBOK 第五版中也是没有的。这部分内容是 PMBOK 第六版中新加的两个独立章节,不过内容不多,非常轻松,重点…

01 - 进阶操作系统(BIOS)

---- 整理自狄泰软件唐佐林老师课程 1. BIOS - Base input & Output system BIOS是上电后第一个运行的程序 BIOS首先检测硬件状态,检测通过后立即进行硬件初始化工作 BIOS会在内存中建立中断向量表(提供硬件访问的方法) BIOS最后将控制…

[附源码]计算机毕业设计JAVA校园飞毛腿系统

[附源码]计算机毕业设计JAVA校园飞毛腿系统 项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis …

前后端分离项目的https加密解密过程二、名词解析及文件生成

前后端分离项目的https加密解密过程二、名词解析及文件生成 密钥仓库keystore文件 Keytool是一个Java数据证书的管理工具 ,Keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中 keystore文件的内容其实就是把私钥、公钥以及公钥对应的地址等信息…

【附源码】计算机毕业设计JAVA众筹平台网站

【附源码】计算机毕业设计JAVA众筹平台网站 目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: JAVA mybati…

leetcode:1579. 保证图可完全遍历【并查集思路】

目录题目截图题目分析ac code总结题目截图 题目分析 从删除比较难,考虑增加增加的过程中无用的边就可以删除考虑alice和bob各自的联通分量最后希望都是1,一开始都是n如果将两个独立的联通分量连起来了,那么连通分量个数减1这里很明显就是用并…

Kafka集群环境搭建及基本使用

前提条件 操作系统:CentOS7服务器:3台Java环境:JDK1.8。安装教程参考JDK1.8安装Zookeeper环境 搭建教程参考Zookeeper集群环境搭建及使用Kafka基础知识参考Kafka角色及功能概览 搭建步骤 下载 执行下载命令wget https://archive.apache.o…

全程软件自动化测试

软件自动化测试的概念 “什么是软件自动化测试?”也许很多人的回答是:“使用自动化测试工具或者编写自动化脚本来自动化测试软件”,还有一些权威网站,比如 WikiPedia 是这样定义的: “在软件测试中,自动化…

(三) 共享模型之管程【共享带来的问题】

一、共享带来的问题 1. 临界区 (1)一个程序运行多个线程本身是没有问题的 (2)问题出在多个线程访问共享资源 1️⃣多个线程读共享资源其实也没有问题 2️⃣在多个线程对共享资源读写操作时发送指令交错,就会出现问题 …

清朝盛衰的六个时间点!

清朝盛衰的整个过程经历了六个时间节点: 一六六一年﹙顺治十八年﹚是第一个时间节点。 正月初六夜半时分,顺治帝预感生命垂危,急命太监传呼麻勒吉与王熙两人赶赴养心殿。帝对王熙说:“朕出痘,势将不起,尔…

三、【react-redux】数据共享

文章目录1、优化项目结构2、添加一个新容器组件2.1、新项目结构2.2、CODE2.2.1、reduc/constant.js2.2.2、redux/actions/person.js2.2.3、redux/reducers/person.js2.2.4、redux/store.js2.2.5、Count.jsx2.2.6、Person.jsx2.3、Result3、总结本示例修改自 上一章 求和Demo 1、…

前端js传入Long类型精度丢失解决办法

目录 问题背景 解决过程 1.对比数据库数据 2.查询资料 解决方法 问题背景 在进行业务开发的 时候发现更新数据库中的一条数据没有成功,查看SQL日志发现SQL正常执行无错误信息,但是受影响行数为0,但是数据是从前端传过来的 ,一…

地图数据设计(四):地图比例尺

前言 比例尺作为地图数学基础的组成部分之一,表示了地图的空间尺度,是地图精度和内容详尽程度的决定因素。今天的文章将从比例尺的基本概念、常见比例尺参数以及SuperMap iDesktopX中比例尺设置三个方面展开。 1 比例尺的基本概念 1.1 定义 一般来说&am…

GmNAC181促进结瘤并提高根瘤的耐盐性

文章信息 题目:GmNAC181 promotes symbiotic nodulation and salt tolerance of nodulation by directly regulating GmNINa expression in soybean 刊名:New Phytologist 作者:Xiaodi Wang,Youning Wang, Xia Li et al. 单位…

【SQL】数据库事务

【SQL】数据库事务事物的ACID特性事务的状态显式事务隐式事务事务的使用举例SQL中的四种隔离级别MySQL中的隔离级别如何设置事务的隔离级别innodb默认支持事务事务是一组逻辑操作单元,使数据从一种状态转变到另一种状态事物的ACID特性 原子性(atomicity…

[附源码]Python计算机毕业设计SSM辽宁科技大学二手车交易平台(程序+LW)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

【OpenCV-Python】教程:3-10 直方图(2)直方图均衡

OpenCV Python 直方图均衡化 【目标】 理解直方图均衡化提升图像的对比度 Histogram Equalization ??? 将图像的直方图拉均衡一些,分散一些;可以提升对比度。 【代码】 通过上面的图像可以看出,高亮度区域较少,需要分散该图像…

新零售行业如何玩转线上服务

如今,随着市场的千变万化,企业的商业模式正在不断经历革新。如线上企业不再单纯走电商路线,纷纷进军线下卖场,而传统门店也在寻找线上突围的机会,通过与电商平台合作,开启线上专卖店。线上线下相结合的新零…

Java并发编程—Thread类中的start()方法如何启动一个线程?

一、java线程的介绍: 在java的开发过程中,很多铁子对于java线程肯定不感到陌生,作为java里面重要的组成部分,这里就从如何创建一个线程给大家进行分析; 二、相关知识引入: ​ 之前我了解过,j…