并发编程理论基础——管程(并发编程的万能钥匙)(七)

什么是管程

  1. Java采用了管程技术,synchronized关键字及wait()、notify()、notifyAll()三个方法都是管程的组成部分
  2. 管程和信号量是等价的,管程和信号量之间可以互相实现
  3. 英文名:Monitor 直译为监视器
  4. 管程指的是管理共享变量以及对共享变量的操作过程,让他们支持并发

MESA模型(一个被广泛应用的模型)

  1. 还有Hasen模型、Hoare模型,MESA使用的范围最广
  2. Java 管程的实现参考的也是 MESA 模型
  3. MESA模型的主要组成:
    • 在管程模型里,共享变量和对共享变量的操作被封装起来,只有一个入库,入口旁边有一个入口等待队列。
    • 在管程模型里,条件变量也被封装,每个条件变量都对应有一个等待队列。
  4. 在并发编程领域,有两大核心问题:一个是互斥,即同一时刻只允许一个线程访问共享资源;另一个是同步,即线程之间如何通信、协作。这两大问题,管程都是能够解决的。
  5. 管程解决互斥问题
    • 将共享变量及其对共享变量的操作统一封装起来。
  6. 管程解决线程间的同步问题
    • 模拟阻塞队列的出队入队过程

wait() 的正确姿势

        对于 MESA 管程来说,有一个编程范式,就是需要在一个 while 循环里面调用 wait()。

三个模型的区别:Hasen 模型、Hoare 模型和 MESA 模型的一个核心区别就是当条件满足后,如何通知相关线程。管程要求同一时刻只允许一个线程执行,那当线程 T2 的操作使线程 T1 等待的条件满足时,T1 和 T2 究竟谁可以执行呢?

  1. Hasen 模型里面,要求 notify() 放在代码的最后,这样 T2 通知完 T1 后,T2 就结束了,然后 T1 再执行,这样就能保证同一时刻只有一个线程执行。
  2. Hoare 模型里面,T2 通知完 T1 后,T2 阻塞,T1 马上执行;等 T1 执行完,再唤醒 T2,也能保证同一时刻只有一个线程执行。但是相比 Hasen 模型,T2 多了一次阻塞唤醒操作。
  3. MESA 管程里面,T2 通知完 T1 后,T2 还是会接着执行,T1 并不立即执行,仅仅是从条件变量的等待队列进到入口等待队列里面。这样做的好处是 notify() 不用放到代码的最后,T2 也没有多余的阻塞唤醒操作。但是也有个副作用,就是当 T1 再次执行的时候,可能曾经满足的条件,现在已经不满足了,所以需要以循环方式检验条件变量。

总结

  1. Java 参考了 MESA 模型,语言内置的管程(synchronized)对 MESA 模型进行了精简。MESA 模型中,条件变量可以有多个,Java 语言内置的管程里只有一个条件变量。
  2. Java 内置的管程方案(synchronized)使用简单,synchronized 关键字修饰的代码块,在编译期会自动生成相关加锁和解锁的代码,但是仅支持一个条件变量而 Java SDK 并发包实现的管程支持多个条件变量,不过并发包里的锁,需要开发人员自己进行加锁和解锁操作。(synchronized和Lock的区别之一)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值