前言
为了支持多线程之间的协作,JDK提供了两个非常重要的接口线程等待 wait()
方法和通知 notify()
方法。这两个方法并不是在Thread类中的,而是输出 Object 类。这也意味着任何对象都可以调用这两个方法。
工作机制
线程A中,调用了 obj.wait()
方法,那么线程A就会停止继续执行,而转为等待状态。线程A会一直等到其他线程调用了obj.notify()
方法。这时,obj 对象就俨然成为多个线程之间的有效通信手段。但唤醒线程是一个随机行为,并不是公平的。
// 标准用法
synchronized (obj) {
while (<condition does not hold>)
obj.wait(); // 释放锁,等待唤醒
... // Perform action appropriate to condition
}
我们应当在循环语句中调用 wait 方法,不能在循环语句外调用。
在等待或跳过 wait 方法前测试 boolean 表达式是否有变化,用这个优化措施来保证执行逻辑。
如果调用 wait 方法前已经调用了 notify 方法,那么这条线程可能就不能被唤醒了(其他线程的 notifyAll 可能会稍后唤醒此线程)。
使用作用域
它们必须包含在对应的 synchronized
语句中,无论是 wait()
还是 notify()
都需要首先获得目标对象的一个监视器。