深入理解“管程模型”

管程:指的是管理共享变量以及对共享变量的操作过程,让他们支持并发。(管理类的成员变量和成员方法,让这个类是线程安全的)

MESA模型

互斥:同一时刻只允许一个线程访问共享资源;

同步:线程之间如何通信、协作。

管程解决互斥问题:将共享变量及其对共享变量的操作统一封装起来;

管程解决同步问题:

 

public class BlockedQueue<T>{
  final Lock lock = new ReentrantLock();
  // 条件变量:队列不满  
  final Condition notFull = lock.newCondition();
  // 条件变量:队列不空  
  final Condition notEmpty = lock.newCondition();

  // 入队
  void enq(T x) {
    lock.lock();
    try {
      while (队列已满){
        // 等待队列不满 
        notFull.await();
      }  
      // 省略入队操作...
      //入队后,通知可出队
      notEmpty.signal();
    }finally {
      lock.unlock();
    }
  }
  // 出队
  void deq(){
    lock.lock();
    try {
      while (队列已空){
        // 等待队列不空
        notEmpty.await();
      }
      // 省略出队操作...
      //出队后,通知可入队
      notFull.signal();
    }finally {
      lock.unlock();
    }  
  }
}

wait()的正确用法

在MESA模型中,需要在while循环里调用wait()

while(条件不满足) {
  wait();
}

Hasen模型、Hoare模型与MESA模型的一个核心区别是:当条件满足后,如何通知相关的线程?

管程要求同一时刻只允许一个线程执行,当线程T2的操作使线程T1等待的条件满足时,T1和T2怎么执行?

Hasen模型:要求notify()的代码放在代码最后,T2通知完T1后,T2结束,T1执行,这样保证同一时刻只有一个线程在执行。

Hoare模型:T2通知完T1后,T2阻塞,T1马上执行;等T1执行完,再唤醒T2,保证同一时刻只有一个线程在执行。但是多了一次阻塞唤醒操作。

MESA模型:T2通知完T1后,T2继续执行,T1并不立刻执行,仅仅是从条件变量的等待队列进入到入口等待队列里面。好处是notify()不用放到代码最后,T2也没有多余的阻塞唤醒操作。副作用是当T1再次执行时,可能曾经满足的条件,现在已经不满足了,所以需要以循环方式检验条件变量。

总结:

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值