標籤: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實現線程間通訊