转载

Java 中的管程

Java是利用 管程 解决并发编程问题的,那么究竟什么是 管程 ?而它又是如何解决并发问题的呢?

什么是管程

管程,英文名是 Monitor ,因此有的时候会被翻译为 监视器 。其实你也许很早就接触到这个概念了,比如 synchronized 关键字,很多文章就介绍过其原理是使用了 监视器 ,只是你那个时候还并不知道 监视器管程 ,其实是一回事。

我们来看看维基百科上的概念:

管程 (英语:Monitors,也称为监视器) 是一种程序结构,结构内的多个子程序(对象或模块)形成的多个工作线程互斥访问共享资源。

感觉这句话听得有点迷糊,但下面这句话应该就很好理解了:

管程提供了一种机制,线程可以临时放弃互斥访问,等待某些条件得到满足后,重新获得执行权恢复它的互斥访问。

我的理解是:我们通过管程管理 Java 中的类,使得类是线程安全的。

这应该是 管程 最终要达到的效果,那么,它是怎么做到的呢?

管程模型

管程这个概念最早来源于操作系统,操作系统发展了那么多年,管程的实现也有多种方式,主流的有三种: Hasen模型Hoare模型MESA模型 , Java 中借鉴的是 MESA模型 ,让我们来重点看一下。

谈到 MESA模型 ,就不得不提到并发主要解决2个核心问题:一个是 互斥 ,即同一时刻只允许一个线程访问共享资源;另一个是 同步 ,即多个线程之间如何通信、协作。

如何解决 互斥 呢?我们可以在操作共享变量之前,增加一个等待队列,每一个线程想要操作共享变量的话,都需要在等待队列中等待,直到管程选出一个线程操作共享变量。

那又是如何解决 同步 的呢?线程在操作共享变量时候,它不一定是直接执行,可能有一些自己的执行条件限制(比如取钱操作要求账户里一定要有钱,出队操作要求队列一定不能是空的),我们将这些限制称之为 条件变量 ,每一个 条件变量 也有自己对应的 等待队列 ,当线程发现自己的 条件变量 不满足时,就进入相应的 等待队列 中排队,直至 条件变量 满足,那么其 等待队列 中的线程也不会是立马执行,而是到最开始 共享变量 对应的 等待队列 中再次排队,重复之前的过程。

可以参考下面这幅图:

Java 中的管程

理论说了那么多,还是来看看用代码是如何实现的吧

实现

首先可以自定一个支持并发的队列

定义生产者和消费者:

做一个测试的main方法:

结果为:

虽然满足我想要的结果,但显示的内容有些奇怪,总是容器先被填满之后,然后容器被清空,感觉原因应该和 可重入锁 有关。

总结

以上就是我对于管程的一些理解,如果大家有什么疑问,可以到我的网站留言。https://death00.github.io/

原文  https://mp.weixin.qq.com/s/XcG7tr9h5XpNGKIdx6r7tg
正文到此结束
Loading...