管程

2020/12/29 posted in  并发基础

管程就是一把解决并发问题的万能钥匙

定义

管程:管理共享变量以及对共享变量的操作过程
核心问题:互斥:同一时刻只允许一个线程访问。同步:线程之间如何通信和协作

管程模型

Hasen 模型

Hoare模型

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();
    }  
  }
}

Hasen 模型、Hoare 模型和 MESA 模型的一个核心区别

  1. Hasen 模型 要求notify放到代码最后,这样T2通知完T1,T2执行借结束,T1继续执行满足同一时刻只有一个线程执行
  2. Hoare 模型 T2通知完T1后,T2阻塞,T1执行,T1执行完后再唤醒T2,满足同一时刻只有一个线程执行,多一次唤醒操作
  3. MESA 模型 T2通知完T1,T2继续执行,T1不会立即执行,而是从条件等待队列进入到入口等待队列;T1再次进入时可能条件已经不满足,所以用循环方式验证