管程:指的是管理共享变量以及对共享变量的操作过程,让他们支持并发。
互斥:同一时刻只允许一个线程访问共享资源;
同步:线程之间如何通信、协作。
MESA模型
在管程的发展史上,先后出现过三种不同的管程模型,分别是Hasen模型、Hoare模型和MESA模型。现在正在广泛使用的是MESA模型。
管程中引入了条件变量的概念,而且每个条件变量都对应有一个等待队列。条件变量和等待队列的作用是解决线程之间的同步问题。
Java中针对管程有两种实现
- 一种是基于Object的Monitor机制,用于synchronized内置锁的实现
- 一种是抽象队列同步器AQS,用于JUC包下Lock锁机制的实现
示例代码
@Slf4j
public class ConditionDemo2 {
private static final ReentrantLock lock = new ReentrantLock();
private static final Condition condition = lock.newCondition();
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
log.debug("t1开始执行....");
lock.lock();
try {
log.debug("t1获取锁....");
// 让线程在obj上一直等待下去
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
log.debug("t1执行完成....");
}
}, "t1").start();
new Thread(() -> {
log.debug("t2开始执行....");
lock.lock();
try {
log.debug("t2获取锁....");
// 让线程在obj上一直等待下去
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
log.debug("t2执行完成....");
}
}, "t2").start();
// 主线程两秒后执行
Thread.sleep(2000);
log.debug("准备获取锁,去唤醒 condition上阻塞的线程");
lock.lock();
try {
// 唤醒condition上所有阻塞的线程
condition.signalAll();
log.debug("唤醒condition上阻塞的线程");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}