簡體   English   中英

我們如何使用notifyAll來確保喚醒后僅繼續一個線程?

[英]How can we use notifyAll to ensure that only one thread continues after wakeup?

摘自Scott的《 編程語言語用學》

要恢復掛在給定對象上的線程,其他一些線程必須執行從引用同一對象的同步語句或方法中預定義的方法通知。 就像等待一樣,notify沒有參數。 響應通知調用,語言運行時系統選擇一個掛在對象上的任意線程並使它可運行。 如果沒有這樣的線程,則通知為無操作。 就像在Mesa中一樣,有時喚醒在給定對象中等待的所有線程可能是適當的。 Java為此提供了一個內置的notifyAll方法。

如果線程正在等待一個以上的條件 (即,如果它們的等待被嵌入不同的循環中),則不能保證“正確的”線程將被喚醒。 為了確保喚醒適當的線程,程序員可以選擇使用notifyAll而不是notify。 為了確保喚醒后只有一個線程繼續運行 ,發現其條件已滿足的第一個線程必須以其他喚醒線程運行時將其喚醒的方式修改對象的狀態。 不幸的是,由於所有等待線程最終都會在其中一個線程每次運行時都重新評估其條件,因此這種解決多條件問題的“解決方案”可能會非常昂貴。

  • 使用notifyAll ,所有喚醒的線程都將爭奪重新獲取該鎖,但是只有一個可以重新獲取該鎖,然后從wait()返回,然后重新評估條件。 那么,為什么說“ 所有等待線程最終將在它們中的一個可以運行時重新評估其條件 ”?

  • 如何重新獲得鎖並重新檢查條件是否為真的線程如何“以其他喚醒的線程開始運行時以其他方式喚醒它們的方式來修改對象的狀態”?

謝謝。

那么為什么這么說:“所有等待線程最終都會在其中一個線程可以運行時重新評估其條件”?

在它將重新獲取並釋放鎖之后,另一個線程將獲取並運行它。 這將一直持續到他們都這樣做為止。

如何重新獲得鎖並重新檢查條件是否為真的線程如何“以其他喚醒的線程開始運行時以其他方式喚醒它們的方式來修改對象的狀態”?

所有線程都將具有以下內容:

while (condition) {
    wait();
}

notifyAll()調用者將在調用條件之前將條件設置為false ,然后喚醒的線程將退出while循環,並在返回並釋放之前將其執行:

condition = true;

所有其他線程將喚醒,檢查條件,停留在while循環中,並調用wait() (返回睡眠狀態)。

另外,您應該使用顯式鎖定機制,因為它允許您為單個鎖定擁有多個 conditions and condition queues ,這將使您能夠使用signal()而不是signalAll() 這樣可以提高性能,減少爭用。

條件API

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM