《Java并发编程实战》课程笔记(六)
管程:并发编程的万能钥匙
什么是管程
- Java 采用的是管程技术,synchronized 关键字及 wait()、notify()、notifyAll() 这三个方法都是管程的组成部分。
- 管程和信号量是等价的,所谓等价指的是用管程能够实现信号量,也能用信号量实现管程。
- 但是管程更容易使用,所以 Java 选择了管程。
- 管程,指的是管理共享变量以及对共享变量的操作过程,让他们支持并发。
MESA 模型
- 在管程的发展史上,先后出现过三种不同的管程模型,分别是:Hasen 模型、Hoare 模型和 MESA 模型。
- 其中,现在广泛应用的是 MESA 模型,并且 Java 管程的实现参考的也是 MESA 模型。
- **在并发编程领域,有两大核心问题:一个是互斥,即同一时刻只允许一个线程访问共享资源;另一个是同步,即线程之间如何通信、协作。**这两大问题,管程都是能够解决的。
- 管程解决互斥问题的思路很简单,就是将共享变量及其对共享变量的操作统一封装起来。
- 那管程如何解决线程间的同步问题呢?
- 管程里引入了条件变量的概念,而且每个条件变量都对应有一个等待队列。
- 那条件变量和条件变量等待队列的作用是什么呢?其实就是解决线程同步问题。
- 假设有个线程 T1 执行阻塞队列的出队操作,执行出队操作,需要注意有个前提条件,就是阻塞队列不能是空的(空队列只能出 Null 值,是不允许的),阻塞队列不空这个前提条件对应的就是管程里的条件变量。
- 如果线程 T1 进入管程后恰好发现阻塞队列是空的,那怎么办呢?就去条件变量对应的等待队列里面等。此时线程 T1 就去“队列不空”这个条件变量的等待队列中等待。
- 再假设之后另外一个线程 T2 执行阻塞队列的入队操作,入队操作执行成功之后,“阻塞队列不空”这个条件对于线程 T1 来说已经满足了,此时线程 T2 要通知 T1,告诉它需要的条件已经满足了。
- 线程 T1 得到通知后,会从等待队列里面出来,但是出来之后不是马上执行,而是重新进入到入口等待队列里面。
wait() 的正确姿势
- 对于 MESA 管程来说,有一个编程范式,就是需要在一个 while 循环里面调用 wait()。这个是 MESA 管程特有的。
notify() 何时可以使用
- 什么时候可以使用 notify() 呢?需要满足以下三个条件:
- 所有等待线程拥有相同的等待条件;
- 所有等待线程被唤醒后,执行相同的操作;
- 只需要唤醒一个线程。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/593259.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!