2013-02-12 73 views
4

我用來寫一個​​塊,如:在同步塊的末尾是否需要notifyAll()?

synchronized(foobar) { 
    // do something 
} 

但是,最近我看到有人寫:

synchronized(foobar) { 
    // do something 
    foobar.notifyAll(); 
} 

是必要的foobar.notifyAll();?如果我忽略它,會發生什麼?

+1

這是爲了防止死鎖 – 2013-02-12 15:59:15

+0

AMR,'同步'是爲了防止死鎖,'notifyAll()'用於指示等待監視器的任何其他線程。 – 2013-02-12 16:00:37

+0

但是,當所有線程都在等待並且沒有通知時,它不是死鎖嗎? – 2013-02-12 16:01:50

回答

1

notifyAll()將告訴睡眠在foobar.wait()中的任何其他線程當前線程即將釋放鎖並且它們可以再次競爭資源。

2

簡短的回答是,這取決於你在做什麼。

如果同步塊的目標僅僅是確保安全地執行對數據結構的訪問/更新,那麼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變爲truefalse的簡單機制。當另一個線程調用setFlag()來更改標誌時,當前正在等待該標誌更改的所有線程都將被notifyAll()喚醒。這是一個例子,其中notifyAll()對於代碼的運行至關重要。


所以瞭解notifynotifyAll代碼是否是必要的,你需要弄清楚如果同一互斥/鎖對象上一些其他的代碼威力呼叫wait

相關問題