共享模型之管程(二)

news2024/11/15 9:39:23

1.Moniter对象

1.1.Java对象头

1>.以32位虚拟机为例
①.普通对象
在这里插入图片描述

Klass Word表示对象的类型,它是一个指针,指向了对象所从属的class;

②.数组对象
在这里插入图片描述

在32位虚拟机中,integer包装类型的长度为12个字节,而int基本数据类型的长度为4个字节;

其中Mark Word结构为:
在这里插入图片描述
2>.64位虚拟机Mark Word结构为:
在这里插入图片描述

Mark Work表示对象自身运行时的数据,它里面包含了哈希值,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳等一系列信息;

更多内容请参考: what-is-in-java-object-header

1.2.Monitor(对象锁)工作原理

monitor被翻译成"监视器"或者"管程",该对象由操作系统提供;

1>.每个Java对象都可以关联一个Monitor对象,如果使用Synchronized给对象上锁(重量级)之后,该对象头的Mark Word就被设置为指向Monitor对象的指针(ptr_to_heavyweight_monitor),锁状态标识从’01’变成’10’;

2>.Monitor结构如下:
在这里插入图片描述
在这里插入图片描述

①.Moniter对象中的Owner属性指向该Monitor对象的所有者/拥有者,即获取Monitor锁的线程;

②.EntryList属性表示阻塞/等待队列,里面存放的是获取锁但是没有成功的线程;

③.WaitSet属性中存放的是已经获得锁(即已经成为monitor对象的所有者),但是条件不满足无法继续运行,为了不占用锁资源,调用wait()方法而进入WAITING状态的线程(锁会被释放,同时唤醒EntryList等待队列中处于BLOCKED阻塞状态的线程,然后这些线程进行锁竞争);

④.BLOCKED和WAITING状态的线程都处于阻塞状态,不占用CPU时间片;

⑤.BLOCKED状态的线程会在monitor所有者线程释放锁时自动被唤醒;而WAITING状态的线程需要在monitor所有者线程调用notify()或notifyAll()方法时才能被唤醒(注意此时的monitor所有者线程并不是之前的monitor所有者线程),而且唤醒之后并不意味着立刻获得锁,仍需进入EntryList等待队列中变成BLOCKED阻塞状态,等待再次被唤醒,然后参与锁竞争;

当执行其他线程中的"obj.notifyAll()或者obj.notify()"这一行代码之后,WaitSet中的WAITING状态的线程会被唤醒尝试获取对象锁,但是此时其他线程Synchronized(obj)代码还没有执行完毕,也就是说对象锁还没有释放,此时被唤醒的线程获取对象锁失败,然后这些线程会进入EntryList等待队列中变成BLOCKED状态,等待被唤醒,重新竞争对象锁;

说明:

①.刚开始obj对象关联的Monitor对象中的Owner属性为null;

②.当线程Thread-2执行synchronized(obj)时就会将obj对象关联的Monitor对象的所有者Owner置为线程Thread-2,obj对象头中的Mark Word变成/设置Monitor对象的地址,并且锁状态标识从’01’变成’10’,每个Monitor对象中只能有一个所有者Owner(即Moniter对象同一时刻只能被一个线程持有);

③.在线程Thread-2上锁的过程中(/获得锁执行同步代码过程中),如果Thread-3,Thread-4,Thread-5也来执行synchronized(obj),这些线程就会进入到EntryList等待队列中被阻塞(BLOCKED);

④.当线程Thread-2执行完同步代码块synchronized(obj)中的代码之后,就会唤醒EntryList中处于BLOCKED阻塞状态的线程来竞争锁,而竞争的过程是非公平的(并不一定是先到先得);

图中WaitSet中的线程Thread-0,Thread-1是之前获得过锁,但是条件不满足无法继续执行而进入WAITING状态的线程;

注意:
①.synchronized必须是进入同一个对象的monitor才有上述的效果;
②.不加synchronized的对象不会关联监视器Monitor,不遵循以上规则;

1.3.从字节码角度分析Monitor对象的工作原理

1>.代码
在这里插入图片描述
2>.编译之后的字节码
在这里插入图片描述
说明:

字节码中有两个monitorexit指令,其中第一个monitorexit指令是在synchronized同步代码块中代码正常执行完成之后使用的,而第二个monitorexit是在synchronized同步代码块中代码执行过程中出现异常使用的,保证synchronized同步代码块中代码执行之后可以正常释放锁,重置Monitor对象,唤醒EntryList中处于阻塞状态的线程,程序代码可以继续运行;

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

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

相关文章

shell第一天练习

题目: 1、在当前主机编写脚本文件history_max.sh显示主机中执行频率最高的前5个命令。 2、判断主机是否存在rhel用户,如果存在则设置密码为redhat,如果不存在则创建用户并设置密码。 3、通过设置变量HISTTIMEFORMAT,使得当执行history命令时…

16. BootStrap

文章目录一、Bootstrap1、概念2、快速入门二、响应式布局三、CSS样式和JS插件1、全局CSS样式2、组件1. 导航条2. 分页条3、插件1. 轮播图四、案例1、案例描述2、案例分析3、实现一、Bootstrap 1、概念 * 概念: 一个前端开发的框架,Bootstrap&#xff0…

Linux网络配置(如何设置静态IP?如何设置查看主机名?)

文章目录Linux网络配置一、网络地址配置1.1. 查看网络地址1.2. 测试两个地址是否连接1.3. Linux系统的网络配置二、主机名以及hosts映射2.1. 查看和设置主机名2.2. hosts映射2.3. DNSLinux网络配置 一、网络地址配置 如果在一台Windows电脑上安装了Linux虚拟机,那…

颤抖开篇,从php角度谈谈IO模型(BIO)

颤抖开篇,从php角度谈谈IO模型(BIO) IO 是什么? 在计算机系统中I/O就是输入(input)和输出(Output)的意思。针对不同的操作对象,可以划分为磁盘I/O模型,网络I/O模型&am…

开发神器VSCode配置C/C++编译环境

hi,小伙伴们大家好,今天给大家介绍一款程序员常用的开发神器VSCode,想必大家肯定有所了解,也有很多小伙伴在日常工作中经常使用。当木荣君初次见到VSCode时,真正的被它惊艳到了,可以说是一见钟情。从此就爱…

13.6-14.8读书笔记

13.6 对象移动 13.6.1 右值引用 概念: 为了支持移动操作,新标准引入了的一种新的引用类型.所谓右值引用就是必须绑定到右值的引用. 通过&&来获得右值引用 int i 42;int &r i;int &&rr i; // 错误,不能将一个右值引用绑定到一个左值上int &r3 …

【python基础_05】面向对象

文章目录1. 类和对象1.1 使用对象组织数据的模版1.2 成员变量和成员方法1.3 实现代码2. 内置方法(魔术方法)2.1 构造方法:__init__()1. 类和对象 1.1 使用对象组织数据的模版 1.2 成员变量和成员方法 1.3 实现代码 1…

jupyter notebook无法启动内核

jupyter notebook无法启动内核问题概述方法一使用Window PowerShell方法二更改文件路径重新启动内核参考问题概述 遇到的问题是在使用jupyter的时候无法正常运行,所以在这里尝试一些办法,在这里进行记录,希望能够帮助到大家 方法一 使用Window PowerShell 首先第一个方法就…

Java IO流 - 释放资源的方式

资源释放的方式 书接上文, 在上一篇文章我们做过一个文件拷贝的练习, 但是在联系中是有释放资源隐患的的, 例如在下面代码中, 在文件释放之前有许多行的逻辑代码; 如果这许多行的逻辑代码有报错, 导致程序不运行, 那么资源就得不到释放 public static void main(String[] args)…

Crack:ActiveReportsJS 3.2.2 EN:ActiveReportsJS

ActiveReportsJS - 高级 JavaScript 报告解决方案 ActiveReportsJS 是一种用于在前端应用程序中可视化数据的报告解决方案。Ω578867473自定义报告布局并将我们的报告设计器和查看器组件集成到 Web 应用程序中,以便在任何平台上预览、导出或打印报告。 使用我们的跨…

WPF+ASP.NET SignalR实现动态折线图

在实际业务中,当后台数据发生变化,客户端能够实时的收到通知,而不是由用户主动的进行页面刷新才能查看,这将是一个非常人性化的设计。有没有那么一种场景,后台数据明明已经发生变化了,前台却因为没有及时刷…

ElementUI——案例2用户管理(基于SpringBoot实现增删改)

1.ElementUI整合SpringBoot前后端分离实现用户增删改查 效果展示 2.前端核心代码 项目目录 main.js引入 import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; import router from ./router import axios from axiosVue.prototype.$http ax…

SQL 存储过程

文章目录存储过程简介存储过程的创建及调用存储过程的删除 如何删除存储过程存储过程的优缺点现需要向学生表中插入新的学生数据。但在插入学生数据的时,需要同 时检查老师表里的数据。如果插入学生的老师不在老师表里,则先向老师表中插入一条老师数据&a…

高级IO-多路转接

高级IO 以前的都是拷贝接口。write什么的就是将字符串拷贝到发送缓冲区中。 应用层等待接收缓冲区填写数据的过程算是IO吗?算 IO等待拷贝数据; 真正的IO的过程就是拷贝的过程。比如等待鱼上钩的时候也算是钓鱼(adj),当把鱼拿上来的时候也…

【Spring篇】代理模式

🍓个人主页:个人主页 🍒系列专栏:SSM框架 目录 一、场景模拟 二、提出问题 三、代理模式 1.静态代理 2.动态代理 一、场景模拟 ①声明接口 声明计算器接口Calculator,包含加减乘除的抽象方法 public interface…

hadoop基础搭建(hadoop+hive+hbase+zk)(一)

文章目录一、基础环境&插件安装(root)二、创建启动脚本,后续使用三、安装JDK(root)四、安装Hadoop五、安装 rsync(root)六、网络配置(4台服务器,root)七、…

使用html2canvas,将页面转换成图片的采坑记录(Web/Taro h5)

使用html2canvas将页面转换成图片的采坑记录 "html2canvas": "^1.4.1","tarojs/taro": "3.4.0-beta.0"问题: 1. 生成的图片很模糊 2. 生成的图片是空白 3. 生成的图片不完整 截图前是这样 截图后这样 截图后的图片图片缺省了一部分…

【消息中间件】1小时快速上手RabbitMQ

前 言 🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端 ☕专栏简介:深入、全面、系统的介绍消息中间件 🌰 文章简介:本文将介绍RabbitMQ,一小时快速上…

Good Bye 2022: 2023 is NEAR D. Koxia and Game

原题链接:Problem - D - Codeforces 题面: 大概意思就是给你一个数组a和数组b,你自己设计一个数组c,Koxia可以从a[i]、b[i]和c[i]中选一个,而Mahiru只能从另外两个里选一个,问你有多少个数组c一定能使Mah…

给GitHub装扮个性化首页

我的主页 如何配置 需要创建一个仓库,仓库名要跟GitHub的用户名一样,我的已经创建过了 喜欢我的主页可以直接fork然后在自己的仓库修改,如果想自己装扮直接看下一步 地址:https://github.com/linweiqian 开始装扮 下面展示仓库状态统计的设…