“嗨,阿米戈!”

“还有更多细节。我们称之为实用建议。”

“假设你有一个等待某事并进入睡眠状态直到满足条件的方法。”

如果集合为空,那么我们等待
public synchronized Runnable getJob()
{
 if (jobs.size() == 0)
  this.wait();

 return jobs.remove(0);
}

“Java 文档非常坚持建议在循环中调用 wait 方法:”

如果集合为空,那么我们等待
public synchronized Runnable getJob()
{
 while (jobs.size() == 0)
  this.wait();

 return jobs.remove(0);
}

“为什么?问题是,如果线程苏醒了,并不代表条件就满足了。可能有二十个这样休眠的线程,都苏醒了,但只有一个能接任务。”

“粗略地说,可能会出现‘误报’。一个好的开发商必须考虑到这一点。”

“原来如此。直接用notify不是更方便吗?”

“那么,如果列表中的任务不止一项呢?通常建议使用 Notify 以进行优化。在所有其他情况下,建议使用 notifyAll 方法。”

“好的。”

"但是还有更多。首先,可能会出现这样一种情况,有人继承了你的类,添加了自己的方法,同时也使用了wait/notifyAll。换句话说,可能会出现独立的wait/notifyAll对等待同一个对象的情况又互不相识。那你该怎么办?”

“始终在循环中调用 wait 并检查循环的终止条件是否为真!”

“是的。为了明确说明你无法逃避这一点,许多开发人员指出,有时线程会自行唤醒。保证不会意外唤醒的线程。这似乎是代码优化的副作用运行 Java 机器。”

“哇哦。明白了。没有循环,wait 方法就不行了。”