在 Java 的并发编程中,什么是等待-通知机制?它是怎么实现的?

在调用 wait()、notify()、notifyAll() 方法时需要先通过 synchronized 对调用对象加锁(互斥锁):

  1. 一个线程调用 wait() 方法后将释放 CPU 执行权和占有的互斥锁,线程状态将由 Runnable 变为 Waiting,并将线程放置到互斥锁对象的等待队列
  2. 其它线程调用 notify() 或 notifyAll() 方法通知等待队列中的线程,表示条件曾经可能满足过。此时等待的线程不会立即从 wait() 方法返回,需要等调用 notify() 或 notifyAll() 方法的线程释放锁之后,等待的线程才有机会从 wait() 方法返回。(管程中的 MESA 模型)
  3. notify() 方法将等待队列中的一个等待线程移到同步队列中;而 notifyAll() 方法则是将等待队列中的所有线程移到同步队列中。被移动的线程状态由 Waiting 变为 Blocked
  4. 当同步队列中的某一线程重新获取到互斥锁,并且要求的条件均满足时,从 wait() 方法返回,继续执行后面的代码语句(wait() 前面的条件判断语句会再次执行吗?用计数器试试。。)。
  5. (否则进入第 1 步)

PS: 对于 wait(long timeout)wait(long timeout, int nanos) 方法,指定了超时参数,若线程等待超过了指定的时间,则会直接从 wait() 方法返回,继续执行后面的代码语句。