java並發編程(十)使用wait/notify/notifyAll實現線程間通訊

來源:互聯網
上載者:User

標籤:eth   target   throw   zed   不能   mic   notify   state   方式   

轉載請註明出處:http://blog.csdn.net/ns_code/article/details/17225469

wait()方法:public final void wait()  throws InterruptedException,IllegalMonitorStateException

 

  wait()方法使得當前線程必須要等待,等到另外一個線程調用notify()或者notifyAll()方法。

 

  當前的線程必須擁有當前對象的monitor,也即lock,就是鎖。

 

  線程調用wait()方法,釋放它對鎖的擁有權,然後等待另外的線程來通知它(通知的方式是notify()或者notifyAll()方法),這樣它才能重新獲得鎖的擁有權和恢複執行。

 

  要確保調用wait()方法的時候擁有鎖,即,wait()方法的調用必須放在synchronized方法或synchronized塊中。

 

  一個小比較:

 

  當線程調用了wait()方法時,它會釋放掉對象的鎖。

 

  另一個會導致線程暫停方法:Thread.sleep(),它會導致線程睡眠指定的毫秒數,但線程在睡眠的過程中是不會釋放掉對象的鎖的。

 

notify()方法public final native void notify() throws IllegalMonitorStateException

 

  notify()方法會喚醒一個等待當前對象的鎖的線程。

 

  如果多個線程在等待,它們中的一個將會選擇被喚醒。這種選擇是隨意的,和具體實現有關。(線程等待一個對象的鎖是由於調用了wait方法中的一個)。

 

  被喚醒的線程是不能被執行的,需要等到當前線程放棄這個對象的鎖。

 

  被喚醒的線程將和其他線程以通常的方式進行競爭,來獲得對象的鎖。也就是說,被喚醒的線程並沒有什麼優先權,也沒有什麼劣勢,對象的下一個線程還是需要通過一般性的競爭。

 

  notify()方法應該是被擁有對象的鎖的線程所調用。

 

  (This method should only be called by a thread that is the owner of this object‘s monitor.)

 

  換句話說,和wait()方法一樣,notify方法調用必須放在synchronized方法或synchronized塊中。

 

 

 

  wait()和notify()方法要求在調用時線程已經獲得了對象的鎖,因此對這兩個方法的調用需要放在synchronized方法或synchronized塊中。

 

  一個線程變為一個對象的鎖的擁有者是通過下列三種方法:

 

  1.執行這個對象的synchronized執行個體方法。

 

  2.執行這個對象的synchronized語句塊。這個語句塊鎖的是這個對象。

 

  3.對於Class類的對象,執行那個類的synchronized、static方法。

 

notifyAll()

     public final native void notifyAll() throws IllegalMonitorStateException

      該方法與notify()方法的工作方式相同,重要的一點差異是:

      notifyAll使所有原來在該對象上wait的線程統統退出wait的狀態(即全部被喚醒,不再等待notify或notifyAll,但由於此時還沒有擷取到該對象鎖,因此還不能繼續往下執行),變成等待擷取該對象上的鎖,一旦該對象鎖被釋放(notifyAll線程退出調用了notifyAll的synchronized代碼塊的時候),他們就會去競爭。如果其中一個線程獲得了該對象鎖,它就會繼續往下執行,在它退出synchronized代碼塊,釋放鎖後,其他的已經被喚醒的線程將會繼續競爭擷取該鎖,一直進行下去,直到所有被喚醒的線程都執行完畢。

 

 

 

     深入理解:

   如果線程調用了對象的wait()方法,那麼線程便會處於該對象的等待池中,等待池中的線程不會去競爭該對象的鎖。

 

   當有線程調用了對象的notifyAll()方法(喚醒所有wait線程)或notify()方法(只隨機喚醒一個wait線程),被喚醒的的線程便會進入該對象的鎖池中,鎖池中的線程會去競爭該對象鎖。

 

   優先順序高的線程競爭到對象鎖的機率大,假若某線程沒有競爭到該對象鎖,它還會留在鎖池中,唯有線程再次調用wait()方法,它才會重新回到等待池中。而競爭到對象鎖的線程則繼續往下執行,直到執行完了synchronized代碼塊,它會釋放掉該對象鎖,這時鎖池中的線程會繼續競爭該對象鎖。

執行個體:https://git.oschina.net/wenjieyatou/threadTest

 

java並發編程(十)使用wait/notify/notifyAll實現線程間通訊

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.