3 回答

TA貢獻1880條經(jīng)驗 獲得超4個贊
這樣的輪詢絕對是最不受歡迎的解決方案。
我假設(shè)您有另一個線程將做一些事情來使條件成立。有幾種同步線程的方法。在您的情況下,最簡單的方法是通過對象發(fā)出通知:
主線程:
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條經(jīng)驗 獲得超8個贊
EboMike的答案和Toby的答案都在正確的軌道上,但是它們都有致命的缺陷。該缺陷稱為丟失通知。
問題是,如果一個線程調(diào)用foo.notify(),它將根本不做任何事情,除非某個其他線程已經(jīng)在foo.wait()調(diào)用中處于休眠狀態(tài)。對象,foo不記得它已收到通知。
有一個原因?qū)е虏辉试S您調(diào)用,foo.wait()或者foo.notify()除非線程在foo上同步。這是因為避免丟失通知的唯一方法是使用互斥量保護條件。完成后,它看起來像這樣:
使用者線程:
try {
synchronized(foo) {
while(! conditionIsTrue()) {
foo.wait();
}
doSomethingThatRequiresConditionToBeTrue();
}
} catch (InterruptedException e) {
handleInterruption();
}
生產(chǎn)者線程:
synchronized(foo) {
doSomethingThatMakesConditionTrue();
foo.notify();
}
更改條件的代碼和檢查條件的代碼都在同一對象上同步,并且使用者線程在等待之前顯式測試條件。wait()當(dāng)條件為真時,用戶無法錯過通知并永遠陷入通話中。
另請注意,這wait()是一個循環(huán)。這是因為,在一般情況下,當(dāng)使用者重新獲取foo鎖并喚醒時,其他一些線程可能再次使條件變?yōu)榧佟<词鼓某绦驘o法做到這一點,在某些操作系統(tǒng)中,foo.wait()即使foo.notify()沒有被調(diào)用,也可能返回。這被稱為“ 偽喚醒”,它被允許發(fā)生,因為它使等待/通知在某些操作系統(tǒng)上更容易實現(xiàn)。
添加回答
舉報