java線程協作—錯失的訊號(thinking in java 筆記)

來源:互聯網
上載者:User

java中多線程協同工作是經常的事,眾所周知這種協同大多是通過wait()和notify()或者notifyAll()來實現的,然而在這個實現中有一點還是值得注意的。請看下面的樣本:

thread1:synchronized(sharedMonitor){      someCondition = false;      sharedMonitor.notify();}thread2:while(someCondition){//point 1synchronized(sharedMonitor){sharedMonitor.wait();}}

如果thread2先執行,執行到point 1的時候線程調度器將線程切換到thread1,thread1執行其設定並執行notify(),而此時線程切回thread2繼續執行完,這個時候,thread2就會進入無限的忙等狀態,因為在它執行wait()之前thread1已經執行完了notify(),因此thread2就錯失這個訊號,這樣就會產生死結。這個問題的解決方案是防止在在someCondition變數上產生競爭條件,如果將thread2修改為下面這樣就可以達到這個目的了:

synchronized(sharedMonitor){while(someCondition){    sharedMonitor.wait();}}

這個時候如果thread1先執行,無論在何處線程發生切換,thread2都不可能執行,因為thread1沒有釋放sharedMonitor對象上的鎖,thread2隻能等待thread1執行完並釋放鎖之後才可以執行,而當thread1執行完後someCondition的值被修改這一事件就會被thread2所捕獲,這樣在someCondition=false的條件下thread2不會進入wait()狀態,相反加入thread2先執行,同樣不論線程切換在何處發生,thread1都必須等到thread2中的synchronized代碼塊全部執行完才可以執行,因為thread2已經擷取了sharedMonitor對象的鎖且必須等到wait()執行完畢之後才會釋放鎖,所以這個時候thread2就不會錯失thread1的notify訊號。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.