“嗨,阿米戈!”
“还有更多细节。我们称之为实用建议。”
“假设你有一个等待某事并进入睡眠状态直到满足条件的方法。”
如果集合为空,那么我们等待
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 方法就不行了。”
GO TO FULL VERSION