《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() 呢?需要满足以下三个条件:
    • 所有等待线程拥有相同的等待条件;
    • 所有等待线程被唤醒后,执行相同的操作;
    • 只需要唤醒一个线程。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值