06.等待-通知机制
总结
- 等待-通知机制让线程在条件不满足时挂起释放 CPU,条件满足时被唤醒,避免空转
- 必须用
while而非if:MESA 模型下被唤醒后条件不一定还满足,需要重新判断 - 优先用
notifyAll,notify随机唤醒可能导致永久等待
一次性申请资源 中用 while(!apply()) 空转等待,浪费 CPU。等待-通知机制让线程在条件不满足时挂起释放 CPU,条件满足时再被唤醒。底层模型是 MESA 管程模型。
1. 用 wait/notify 改进 Allocator
class Allocator {
private List<Object> als = new ArrayList<>();
synchronized void apply(Object from, Object to) throws InterruptedException {
while (als.contains(from) || als.contains(to)) {
this.wait(); // 挂起,释放锁,等待唤醒后重新判断条件
}
als.add(from);
als.add(to);
}
synchronized void free(Object from, Object to) {
als.remove(from);
als.remove(to);
this.notifyAll(); // 唤醒所有等待线程
}
}
2. 关键注意点
- 必须用
while而非if:线程被唤醒后条件不一定还满足(MESA 模型特性),需要重新判断 - 优先用
notifyAll:notify随机唤醒一个,可能唤醒错误的线程导致永久等待 - 何时可以用
notify:所有等待线程条件相同、操作相同、且只需唤醒一个
Condition 是 wait/notify 的升级版,支持多个等待队列,可以精确唤醒特定条件的线程。