java并发-管程

文章目录

什么是管程

Java中,每个对象其实都一个Monitor(java中翻译为监视器),Java中提供的synchronized关键字及wait()、notify()、notifyAll()方法,都是Monitor的一部分

Monitor
Monitor可以理解为一个同步工具或一种同步机制,通常被描述为一个对象。每一个Java对象就有一把看不见的锁,称为内部锁或者Monitor锁。

Monitor是线程私有的数据结构,每一个线程都有一个可用monitor record列表,同时还有一个全局的可用列表。每一个被锁住的对象都会和一个monitor关联,同时monitor中有一个Owner字段存放拥有该锁的线程的唯一标识,表示该锁被这个线程占用。

Java 参考了 MESA 模型,语言内置的管程(synchronized)对 MESA 模型进行了精简。MESA 模型中,条件变量可以有多个,Java 语言内置的管程里只有一个条件变量。

synchronized关键字是JVM实现的,底层是基于操作系统Mutex Lock实现;但他们都是基于MESA模型实现的。

Monitor在OS中或者别处的翻译是管程,我也更倾向于翻译为管程,Java中使用的是MESA管程。

在管程的发展史上,先后出现过三种不同的管程模型,分别是:Hasen 模型、Hoare 模型和 MESA 模型。其中,现在广泛应用的是 MESA 模型,并且 Java 管程的实现参考的也是 MESA 模型。

管程模型解决并发2大核心问题:一个是互斥,即同一时刻只允许一个线程访问共享资源;另一个是同步,即线程之间如何通信、协作。

管程模型的代码化语义:
在这里插入图片描述在管程模型里,共享变量和对共享变量的操作是被封装起来的(图: 管程模型的代码化语义)。

MESA 管程模型:
在这里插入图片描述管程里还引入了条件变量的概念,而且每个条件变量都对应有一个等待队列。如图,条件变量 A 和条件变量 B 分别都有自己的等待队列。

还是以第一幅图中的,共享变量队列说明(用一个阻塞队列来举例子,而这个阻塞队列跟monitor里的队列没有关系)。

假设有个线程 T1 执行出队操作,不过需要注意的是执行出队操作,有个前提条件,就是队列不能是空的,而队列不空这个前提条件就是管程里的条件变量。 如果线程 T1 进入管程后恰好发现队列是空的,那怎么办呢?等待啊,去哪里等呢?就去条件变量对应的等待队列里面等。此时线程 T1 就去“队列不空”这个条件变量的等待队列中等待。

再假设之后另外一个线程 T2 执行入队操作,入队操作执行成功之后,“队列不空”这个条件对于线程 T1 来说已经满足了,此时线程 T2 要通知 T1,告诉它需要的条件已经满足了。当线程 T1 得到通知后,会从等待队列里面出来,但是出来之后不是马上执行,而是重新进入到入口等待队列里面。

条件变量及其等待队列我们讲清楚了,下面再说说 wait()、notify()、notifyAll() 这三个操作。**前面提到线程 T1 发现“队列不空”这个条件不满足,需要进到对应的等待队列里等待。这个过程就是通过调用 wait() 来实现的。**如果我们用对象 A 代表“队列不空”这个条件,那么线程 T1 需要调用 A.wait()。同理当“队列不空”这个条件满足时,线程 T2 需要调用 A.notify() 来通知 A 等待队列中的一个线程,此时这个队列里面只有线程 T1。至于 notifyAll() 这个方法,它可以通知等待队列中的所有线程。

  1. 管程是一种概念,任何语言都可以通用。
  2. 在java中,每个加锁的对象都绑定着一个管程(监视器)
  3. 线程访问加锁对象,就是去拥有一个监视器的过程。

总结起来就是,管程就是一个对象监视器。任何线程想要访问该资源,就要排队进入监控范围。进入之后,接受检查,不符合条件,则要继续等待,直到被通知,然后继续进入监视器。

管程是定义了一个数据结构和能为并发所执行的一组操作,这组操作能够进行同步和改变管程中的数据。这相当于对临界资源的同步操作都集中进行管理,凡是要访问临界资源的进程或线程,都必须先通过管程,由管程的这套机制来实现多进程或线程对同一个临界资源的互斥访问和使用。管程的同步主要通过condition类型的变量(条件变量),条件变量可执行操作wait()和signal()。管程一般是由语言编译器进行封装,体现出OOP中的封装思想,管程模型和面向对象高度契合的。 管程只是一种解决并发问题的模型而已。

参考

Java并发编程模拟管程(霍尔Hoare管程、汉森Hansan管程、MESA管程)
参考URL: https://blog.csdn.net/qq_34666857/article/details/103189107
管程:并发编程的万能钥匙
参考URL: https://time.geekbang.org/column/article/86089
信号量与管程
参考URL: https://www.cnblogs.com/kkkkkk/p/5543799.html

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付 29.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值