2010-03-29 79 views
19

我想知道爲什麼線程自發地從java中的wait()喚醒。
這是設計決定嗎?這是一個妥協嗎?線程爲什麼自發地從wait()中喚醒?

編輯:(從Java併發實踐,P 300)

wait甚至被允許返回 「不合邏輯」 - 不響應任何 線程調用通知。

而且作者所述:

這就像一個鬆散的 連接,使鍾熄滅 烤麪包機當面包是準備好,但也 有時當它是沒有準備好。

這就是爲什麼你總是有如下代碼

synchronized(this){ 
    while(!condition) 
     wait(); 
    } 
} 

永不

synchronized(this){ 
    if(!condition){ 
     wait(); 
    } 
} 

即使條件的轉換隻能從 falsetrue

+0

不,請參閱我的編輯.. – 2010-03-29 20:32:05

+0

好的,我刪除了我的評論,因爲它看起來像你是對的。 – 2010-03-29 20:43:22

回答

24

這些自發喚醒也被稱爲「虛假喚醒」。在Java規範中,對於jvm實現,虛假喚醒允許允許(儘管不鼓勵)。

它們被允許的原因是因爲許多實現可能基於pthreads(POSIX線程),具有此行爲。爲什麼?

Wikipedia:

據大衛R. Butenhof的 編程與POSIX線程ISBN 0-201-63392-2 :「這意味着,當你 等待條件變量時, 等待可能(偶爾)時,沒有 線程專門廣播或 暗示條件變量的回報。 虛假喚醒可能聽起來很奇怪, 但在一些多處理器系統, 使病情完全喚醒 可預測的可能會大大減緩所有條件變量的操作。導致虛假 喚醒的 比賽條件應該算是罕見的。」

+0

感謝POSIX的背景,非常翔實! – Ricket 2010-03-29 20:44:41

+0

這很有道理。謝謝! – 2010-03-29 20:50:28

+0

我認爲我們相隔約60秒發佈 – 2010-03-29 20:59:19

10

很難明確回答這個問題,因爲Java語言規範沒有規定爲什麼一個JVM實現可能要做到這一點(只有它指定它可以,in this section),但我發現a pretty interesting history of spurious wake-ups on Wikipedia

約POSIX線程實際的文章,但我不認爲這是太遠牽強假設在Java中的線程是有點POSIX線程的行爲的影響:

虛假喚醒可能聽起來很奇怪,但在一些多處理器系統上,使條件喚醒完全可預測可能會顯着減慢所有條件變量操作。導致虛假喚醒的競賽條件應該被認爲是罕見的。

這句話是從大衛R. Butenhof,誰再繼續說:

雖然還有誰認爲該工作組的確有些成員,這是理論上可以設想,有可能是這樣一個實現,那不是真正的原因。 (而且他們永遠無法證明這一點。)POSIX線程是實用硬實時程序員和主要學術研究人員之間的緊張關係的結果。虛假喚醒是學術計算機科學家集團的機制,以確保每個人都必須編寫乾淨的代碼來檢查和驗證謂詞!

「但是(也許),主要寄生(或至少arcanely哲學)‘效率’的說法去了更好地與實時的人,真正的原因是通常的理由退居次席。

」我曾多次想過如何構建一個真正具有虛假喚醒的正確和實用的實現。我從來沒有設法構建一個例子。並不意味着沒有一個,它是一個很好的故事。