3 回答

TA貢獻1880條經驗 獲得超4個贊
這樣的輪詢絕對是最不受歡迎的解決方案。
我假設您有另一個線程將做一些事情來使條件成立。有幾種同步線程的方法。在您的情況下,最簡單的方法是通過對象發出通知:
主線程:
synchronized(syncObject) {
try {
// Calling wait() will block this thread until another thread
// calls notify() on the object.
syncObject.wait();
} catch (InterruptedException e) {
// Happens if someone interrupts your thread.
}
}
其他線程:
// Do something
// If the condition is true, do the following:
synchronized(syncObject) {
syncObject.notify();
}
syncObject本身可以很簡單Object。

TA貢獻1772條經驗 獲得超8個贊
EboMike的答案和Toby的答案都在正確的軌道上,但是它們都有致命的缺陷。該缺陷稱為丟失通知。
問題是,如果一個線程調用foo.notify(),它將根本不做任何事情,除非某個其他線程已經在foo.wait()調用中處于休眠狀態。對象,foo不記得它已收到通知。
有一個原因導致不允許您調用,foo.wait()或者foo.notify()除非線程在foo上同步。這是因為避免丟失通知的唯一方法是使用互斥量保護條件。完成后,它看起來像這樣:
使用者線程:
try {
synchronized(foo) {
while(! conditionIsTrue()) {
foo.wait();
}
doSomethingThatRequiresConditionToBeTrue();
}
} catch (InterruptedException e) {
handleInterruption();
}
生產者線程:
synchronized(foo) {
doSomethingThatMakesConditionTrue();
foo.notify();
}
更改條件的代碼和檢查條件的代碼都在同一對象上同步,并且使用者線程在等待之前顯式測試條件。wait()當條件為真時,用戶無法錯過通知并永遠陷入通話中。
另請注意,這wait()是一個循環。這是因為,在一般情況下,當使用者重新獲取foo鎖并喚醒時,其他一些線程可能再次使條件變為假。即使您的程序無法做到這一點,在某些操作系統中,foo.wait()即使foo.notify()沒有被調用,也可能返回。這被稱為“ 偽喚醒”,它被允許發生,因為它使等待/通知在某些操作系統上更容易實現。
添加回答
舉報