Java:notify()與notifyAll()重溫
雖然人們常說notify()只喚醒一個等待線程,但notifyAll () 喚醒所有等待線程,理解它們的實際意義至關重要。
核心區別
兩種方法都會喚醒等待線程,但無論使用哪種方法,一次只能授予一個線程獲取監視器。這個選擇過程是非確定性的,取決於VM或底層系統執行緒調度程序。
notifyAll()的值
在大多數情況下,notifyAll()應該透過notify() 來使用。使用notify()時,只能選擇一個執行緒來執行。這可能會導致死鎖,如以下範例所示:
public class ProducerConsumerBroken { private Object[] buf; public synchronized void put(Object o) { while (buf.length == MAX_SIZE) wait(); buf[next] = o; notify(); } public synchronized Object get() { while (buf.length == 0) wait(); return buf[next--]; } }
在此範例中,notify() 可能會導致死鎖,因為系統執行緒調度程式可能會持續偏向一個線程,而使其他執行緒無限期掛起。
使用notifyAll()避免死鎖
透過使用notifyAll() 時,所有等待執行緒(如果有)都被喚醒,從而使每個執行緒都有公平的機會獲取鎖並繼續執行。這消除了死鎖的可能性。
何時使用notifyAll()
每當您想要確保所有等待執行緒都知道它們正在處理的物件時,請使用notifyAll()正在等待的已經改變了。當您無法預測需要通知哪個執行緒或多個執行緒可能正在等待同一鎖時,這一點尤其重要。
建議
一般情況根據經驗,總是使用notifyAll()。這將防止潛在的死鎖並確保執行緒調度的公平性。
以上是什麼時候應該在 Java 中使用「notifyAll()」?的詳細內容。更多資訊請關注PHP中文網其他相關文章!