Java monitor机制使用方法解析
作者:shemlothae 时间:2023-11-09 11:25:56
monitor概念
管程,监视器。在操作系统中,存在着semaphore和mutex,即信号量和互斥量,使用基本的mutex进行开发时,需要小心的使用mutex的down和up操作,否则容易引发死锁问题。为了更好的编写并发程序,在mutex和semaphore基础上,提出了更高层次的同步原语,实际上,monitor属于编程语言的范畴,C语言不支持monitor,而java支持monitor机制。
一个重要特点是,在同一时间,只有一个线程/进程能进入monitor所定义的临界区,这使得monitor能够实现互斥的效果。无法进入monitor的临界区的进程/线程,应该被阻塞,并且在适当的时候被唤醒。显然,monitor作为一个同步工具,也应该提供这样管理线程/进程的机制。
monitor这个机制之所以被称为:更高级的原语,它不可避免的需要对外屏蔽这些机制,并且在内部实现这些机制,使得monitor成为一个简洁易用的借口。
monitor基本元素
临界区
monitor对象和锁
条件变量以及定义在monitor对象上的wait,signal操作
使用monitor主要是为了互斥进入临界区,为了能够阻塞无法进入临界区的进程,线程,需要一个monitor object来协助,这个object内部会有相应的数据结构,例如列表,用来保存被阻塞的线程;同时由于monitor机制本质是基于mutex原语的,所以object必须维护一个基于mutex的锁。
此外,为了在适当的时候能够阻塞和唤醒 进程/线程,还需要引入一个条件变量,这个条件变量用来决定什么时候是“适当的时候”,这个条件可以来自程序代码的逻辑,也可以是在 monitor object 的内部,总而言之,程序员对条件变量的定义有很大的自主性。不过,由于 monitor object 内部采用了数据结构来保存被阻塞的队列,因此它也必须对外提供两个 API 来让线程进入阻塞状态以及之后被唤醒,分别是 wait 和 notify。
monitor在java中的实现
临界区的圈定
被synchronized关键字修饰的方法,代码块,就是monitor机制的临界区
monitor object
在上述synchronized关键字被使用时,往往需要指定一个对象与之关联,例如synchronized(this),总之,synchronized需要管理一个对象,这个对象就是monitor object。
monitor机制中,monitor 我不检测题充当着维护mutex和wait, signalAPI来管理线程的阻塞和唤醒。
Java 对象存储在内存中,分别分为三个部分,即对象头、实例数据和对齐填充,而在其对象头中,保存了锁标识;同时,java.lang.Object 类定义了 wait(),notify(),notifyAll() 方法,这些方法的具体实现,依赖于一个叫 ObjectMonitor 模式的实现,这是 JVM 内部基于 C++ 实现的一套机制,基本原理如下所示:
当一个线程需要获取 Object 的锁时,会被放入 EntrySet 中进行等待,如果该线程获取到了锁,成为当前锁的 owner。如果根据程序逻辑,一个已经获得了锁的线程缺少某些外部条件,而无法继续进行下去(例如生产者发现队列已满或者消费者发现队列为空),那么该线程可以通过调用 wait 方法将锁释放,进入 wait set 中阻塞进行等待,其它线程在这个时候有机会获得锁,去干其它的事情,从而使得之前不成立的外部条件成立,这样先前被阻塞的线程就可以重新进入 EntrySet 去竞争锁。这个外部条件在 monitor 机制中称为条件变量。
来源:https://www.cnblogs.com/shemlo/p/11605681.html
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java使用substring()截取(提取)子字符串
![](https://img.aspxhome.com/file/2023/0/62670_0s.jpg)
Java springboot yaml语法注解
基于C#的UDP协议的同步通信实现代码
Android实现USB扫码枪获取扫描内容
java中日期格式化的大坑
Mybatis resultMap标签继承、复用、嵌套方式
C#实现将DataTable内容输出到Excel表格的方法
![](https://img.aspxhome.com/file/2023/4/68084_0s.png)
SpringBoot配置文件中密码属性加密的实现
![](https://img.aspxhome.com/file/2023/8/64018_0s.jpg)
C#远程获取图片文件流的方法
详解spring boot引入外部jar包的坑
![](https://img.aspxhome.com/file/2023/4/61314_0s.jpg)
解析Spring Mvc Long类型精度丢失问题
![](https://img.aspxhome.com/file/2023/5/61275_0s.png)
java生成指定范围随机数的多种代码
![](https://img.aspxhome.com/file/2023/3/60383_0s.png)
C#组合函数的使用详解
Java实现窗体程序显示日历
![](https://img.aspxhome.com/file/2023/4/72534_0s.jpg)
关于@RequestLine的使用及配置
![](https://img.aspxhome.com/file/2023/7/114057_0s.jpg)
C#中使用反射遍历一个对象属性及值的小技巧
Json字符串与Object、List、Map的互转工具类
关于Java中修饰符的总结(fina除外)
Spring Boot启动过程(四)之Spring Boot内嵌Tomcat启动
![](https://img.aspxhome.com/file/2023/7/58577_0s.png)
Java基础之final关键字作用案例
![](https://img.aspxhome.com/file/2023/6/62126_0s.png)