前言

为了支持多线程之间的协作,JDK提供了两个非常重要的接口线程等待 wait() 方法和通知 notify() 方法。这两个方法并不是在Thread类中的,而是输出 Object 类。这也意味着任何对象都可以调用这两个方法。

工作机制

线程A中,调用了 obj.wait() 方法,那么线程A就会停止继续执行,而转为等待状态。线程A会一直等到其他线程调用了obj.notify() 方法。这时,obj 对象就俨然成为多个线程之间的有效通信手段。但唤醒线程是一个随机行为,并不是公平的。

  1. // 标准用法
  2. synchronized (obj) {
  3. while (<condition does not hold>)
  4. obj.wait(); // 释放锁,等待唤醒
  5. ... // Perform action appropriate to condition
  6. }

我们应当在循环语句中调用 wait 方法,不能在循环语句外调用。
在等待或跳过 wait 方法前测试 boolean 表达式是否有变化,用这个优化措施来保证执行逻辑。
如果调用 wait 方法前已经调用了 notify 方法,那么这条线程可能就不能被唤醒了(其他线程的 notifyAll 可能会稍后唤醒此线程)。

使用作用域

它们必须包含在对应的 synchronized 语句中,无论是 wait() 还是 notify() 都需要首先获得目标对象的一个监视器。
等待(wait)和通知(notify) - 图1