[英]the behavior of Java wait() method
假設令牌機器一次只能發行一個令牌。 規則是必須先消耗一個令牌,然后才能創建另一個令牌。
class TokenMachine {
private int tokenID;
private boolean tokenExists = false;
public synchronized void createToken(int coup){
...
}
public synchronized int consumeToken(){
...
}
}
public synchronized void createToken(int coup) {
while(tokenExists) { //can I change 'while' to 'if'?
wait(); //in a try-catch block
}
this.tokenID = coup;
tokenExists = true;
notify();
}
public synchronized int consumeToken() {
while(!tokenExists) { //can I change 'while' to 'if'?
wait(); //in a try-catch block
}
tokenExists = false;
notify();
return tokenID;
}
我的問題是,我可以在不破壞規則的情況下將之前代碼中的“ while”表達式更改為“ if”嗎? 非常感謝。
謝謝大家回答我的問題,我在網上進行了很多檢查,發現以下信息對您有幫助:線程也可以喚醒,而不會被通知,中斷或超時,即所謂的虛假喚醒。 盡管在實踐中這種情況很少發生,但是應用程序必須通過測試應該導致線程喚醒的條件來防范它,並在條件不滿足時繼續等待。 換句話說,等待應該總是在循環中發生。
顯然,虛假喚醒是一個問題(我懷疑這是一個眾所周知的問題),對於專業開發人員而言,中級人員知道會發生這種情況,但JLS第三版對此做了澄清,該版本已作為JDK 5開發的一部分進行了修訂。 JDK 5中的wait方法的javadoc也已更新
您需要使用while
來避免由於虛假喚醒而喚醒線程。 在虛假喚醒的情況下,可以在不調用notify()
情況下喚醒線程。 while
循環將重新檢查條件,並且僅當它是真正的notify
調用而不是偽激活時才繼續。
class TokenMachine {
ArrayBlockingQueue<Integer> q=new ArrayBlockingQueue<Integer>(1);
public synchronized void createToken(int coup){
q.put(coup);
}
public synchronized int consumeToken(){
return q.get();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.