我用來寫一個塊,如:在同步塊的末尾是否需要notifyAll()?
synchronized(foobar) {
// do something
}
但是,最近我看到有人寫:
synchronized(foobar) {
// do something
foobar.notifyAll();
}
是必要的foobar.notifyAll();
?如果我忽略它,會發生什麼?
我用來寫一個塊,如:在同步塊的末尾是否需要notifyAll()?
synchronized(foobar) {
// do something
}
但是,最近我看到有人寫:
synchronized(foobar) {
// do something
foobar.notifyAll();
}
是必要的foobar.notifyAll();
?如果我忽略它,會發生什麼?
你不需要需要來做到這一點。如果對象(此處爲foobar
)等待通知,則只需執行此操作。僅通知Wakes up all threads that are waiting on this object's monitor.
在Java中,您可以使用wait()
,notify()
和notifyAll()
來實現線程協調。請參閱How to use wait and notify in Java?
notifyAll()將告訴睡眠在foobar.wait()中的任何其他線程當前線程即將釋放鎖並且它們可以再次競爭資源。
簡短的回答是,這取決於你在做什麼。
如果同步塊的目標僅僅是確保安全地執行對數據結構的訪問/更新,那麼notify()
或notifyAll()
沒有任何用處。
在另一方面,如果我們的目標是實現一個「條件變量」,那麼notify()
或notifyAll()
電話與電話wait
這樣......例如工作:以上
private boolean flag;
private final Object mutex = new Object();
public void awaitFlag(boolean flag) {
synchronized (mutex) {
while (this.flag != flag) {
mutex.wait();
}
}
}
public void setFlag(boolean flag) {
synchronized (mutex) {
this.flag = flag;
mutex.notifyAll();
}
}
實現線程調用awaitFlag()
等待flag
變爲true
或false
的簡單機制。當另一個線程調用setFlag()
來更改標誌時,當前正在等待該標誌更改的所有線程都將被notifyAll()
喚醒。這是一個例子,其中notifyAll()
對於代碼的運行至關重要。
所以瞭解notify
或notifyAll
代碼是否是必要的,你需要弄清楚如果同一互斥/鎖對象上一些其他的代碼威力呼叫wait
。
這是爲了防止死鎖 – 2013-02-12 15:59:15
AMR,'同步'是爲了防止死鎖,'notifyAll()'用於指示等待監視器的任何其他線程。 – 2013-02-12 16:00:37
但是,當所有線程都在等待並且沒有通知時,它不是死鎖嗎? – 2013-02-12 16:01:50