“嗨,阿米戈!”

“還有更多細節。我們稱之為實用建議。”

“假設你有一個等待某事並進入睡眠狀態直到滿足條件的方法。”

如果集合為空,那麼我們等待
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 方法不好。”