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++ 实现的一套机制,基本原理如下所示:

Java monitor机制使用方法解析

当一个线程需要获取 Object 的锁时,会被放入 EntrySet 中进行等待,如果该线程获取到了锁,成为当前锁的 owner。如果根据程序逻辑,一个已经获得了锁的线程缺少某些外部条件,而无法继续进行下去(例如生产者发现队列已满或者消费者发现队列为空),那么该线程可以通过调用 wait 方法将锁释放,进入 wait set 中阻塞进行等待,其它线程在这个时候有机会获得锁,去干其它的事情,从而使得之前不成立的外部条件成立,这样先前被阻塞的线程就可以重新进入 EntrySet 去竞争锁。这个外部条件在 monitor 机制中称为条件变量。

来源:https://www.cnblogs.com/shemlo/p/11605681.html

标签:java,monitor,机制
0
投稿

猜你喜欢

  • Java使用substring()截取(提取)子字符串

    2023-09-29 17:02:04
  • Java springboot yaml语法注解

    2023-06-17 08:13:35
  • 基于C#的UDP协议的同步通信实现代码

    2023-11-14 09:13:58
  • Android实现USB扫码枪获取扫描内容

    2023-09-08 00:56:31
  • java中日期格式化的大坑

    2021-07-02 09:42:59
  • Mybatis resultMap标签继承、复用、嵌套方式

    2023-06-27 13:27:43
  • C#实现将DataTable内容输出到Excel表格的方法

    2023-05-01 15:20:38
  • SpringBoot配置文件中密码属性加密的实现

    2022-07-08 18:32:03
  • C#远程获取图片文件流的方法

    2023-03-17 15:15:18
  • 详解spring boot引入外部jar包的坑

    2021-07-29 10:49:49
  • 解析Spring Mvc Long类型精度丢失问题

    2021-11-06 12:27:37
  • java生成指定范围随机数的多种代码

    2023-04-28 07:51:15
  • C#组合函数的使用详解

    2022-01-24 04:22:41
  • Java实现窗体程序显示日历

    2022-09-14 11:01:59
  • 关于@RequestLine的使用及配置

    2023-09-23 20:52:19
  • C#中使用反射遍历一个对象属性及值的小技巧

    2021-12-10 18:15:43
  • Json字符串与Object、List、Map的互转工具类

    2023-04-30 16:08:16
  • 关于Java中修饰符的总结(fina除外)

    2023-11-22 23:15:57
  • Spring Boot启动过程(四)之Spring Boot内嵌Tomcat启动

    2023-09-21 00:16:18
  • Java基础之final关键字作用案例

    2022-11-02 19:23:35
  • asp之家 软件编程 m.aspxhome.com