我有一個線程不時更新它的狀態,我想要第二個線程能夠等待第一個線程完成。事情是這樣的:在Java中等待事件 - 它有多困難?
Thread 1:
while(true) {
...do something...
foo.notifyAll()
...wait for some condition that might never happen...
...
}
Thread 2:
...
foo.wait();
...
現在,這看起來不錯,所有除非線程1的notifyAll的()之前線程2的wait(),運行在這種情況下,線程2個等待直到線程1通知再次(可能永遠不會發生) 。
我可能的解決方案:
一)我可以使用的CountDownLatch或未來,但兩者有本質上它們只運行一次的問題。也就是說,在線程1的while循環中,我需要創建一個新的foo來等待每次,並且線程2需要詢問哪個foo要等待。我對簡單地寫
while(true) {
foo = new FutureTask();
...
foo.set(...);
...wait for a condition that might never be set...
...
}
一種不好的感覺,因爲我擔心,在富=新FutureTask(),當有人等着老FOO(對於「某些原因」,設置不叫會發生什麼,如異常處理中的錯誤)?
b)或我可以用一個信號:
class Event {
Semaphore sem;
Event() { sem = new Semaphore(1); sem . }
void signal() { sem.release(); }
void reset() { sem.acquire(1); }
void wait() { if (sem.tryAcquire(1)) { sem.release(); } }
}
但我擔心,有一些競爭條件,如果將多個線程wait()就爲它而另外一個信號()S和復位( )秒。
問:
有什麼類似於Windows事件行爲的Java API嗎?或者,如果你鄙視Windows,像golang的WaitGroup(即允許countUp())的CountDownLatch)?什麼?
如何手動做到這一點:
線程2不能簡單地等待,因爲虛假喚醒,並在Java中沒有辦法知道爲什麼的Object.wait()返回。所以我需要一個條件變量來存儲事件是否有信號。線程2:
synchronized(foo) {
while(!condition) {
foo.wait();
}
}
而線程1當然在同步塊中設置條件爲真。感謝週末的提示!
是否有一個包裝該行爲的現有類?
還是我需要複製和粘貼代碼嗎?
什麼問題,你實際上試圖解決?雖然我確信這個問題可以得到解決,但我仍然想問一下,所以我們知道這是您的問題的正確解決方案。這種與線程和信號量有關的問題雖然被很好地理解,但由於小錯誤而容易失敗,因此可能會有更易讀易懂的方法來實現您想要實現的目標。特別是它聽起來像一個簡單的evenlistener模式,聽衆註冊事件的來源會更合適。 – Thor84no 2011-12-19 13:54:42
是的,一個事件監聽器可以通過讓線程1「push」更新來解決這個問題。這通常是優選的方法,例如在服務器環境中。然而,我偶爾碰到線程安全「拉」更新的問題,直到現在我從來沒有一個乾淨的解決方案。 – Kosta 2011-12-19 16:29:33