執行緒通知與等待

2021-10-19 21:29:25 字數 1273 閱讀 7233

乙個執行緒呼叫乙個共享變數的wait()方法時,該執行緒會被阻塞掛起。呼叫wait的前提是該執行緒有獲取共享變數的監視器鎖。

獲取監視器鎖:

(1)synchronize(共享變數)

(2)在在共享變數的方法前加synchronize關鍵字,呼叫該方法。

若執行緒沒有獲取監視器鎖而呼叫了wait()則會丟擲illegalmonitorstateexception異常。

停止執行緒阻塞並返回:

(1)其他執行緒呼叫共享物件的notify和notifyall方法

(2)其他執行緒呼叫該執行緒的interrupt方法,該執行緒會丟擲interruptedexception異常。

wait帶引數方法:

wait(long timeout):執行緒呼叫該方法掛起後如果沒有在timeout ms時間內被其他執行緒喚醒會因為超時而返回。如果引數為負數則會丟擲異常。

wait(long timeout, int nanos):當nanos大於0時使timeout遞增1.

虛假喚醒:(1)乙個執行緒有可能在沒有被其他執行緒用notify、notifyall喚醒的情況下被喚醒,(2)被中斷,(3)等待超時

避免虛假喚醒:

synchronized

(obj)

}

當乙個執行緒呼叫共享物件的notify()方法後會隨機喚醒乙個在該共享變數上因呼叫wait方法被掛起的執行緒。而notifyall()則是喚醒所有符合上訴條件的執行緒。

注意,兩個方法都不能保證被喚醒的執行緒一定會直接執行,只是使被喚醒的執行緒競爭鎖。由於被喚醒的執行緒需要競爭監視器鎖,當獲取到該鎖以後才能繼續執行,所有被喚醒的執行緒並不會立刻從wait方法返回,而是當獲取到共享變數的監視器鎖以後再返回。

在乙個執行緒內呼叫另乙個執行緒的join()方法後,主線程會阻塞,等待子執行緒執行完畢後再繼續執行,當然,在呼叫join()方法前,子執行緒需要先start()啟動。

sleep是乙個靜態方法,呼叫thread.sleep()方法時,使當前執行緒休眠一定的時間後參與cpu排程。sleep方法只會讓出cpu資源並不會釋放鎖等監視器資源。

sleep與wait的區別在於,呼叫wait後執行緒進入阻塞態並釋放鎖資源,而sleep不會。所以呼叫wait需要獲取共享變數的鎖,而sleep則不用。

yield方法也是乙個靜態方法,呼叫yield方法是使當前程序讓出cpu進入就緒態,使執行緒排程器進入下一輪的執行緒排程。由於讓出cpu的執行緒是進入就緒態,所以有可能會再次被分配到cpu資源繼續執行。

yield與sleep區別是呼叫yield後執行緒進入就緒態,而sleep進入阻塞態。

執行緒通知與等待

當乙個執行緒呼叫乙個共享變數的 wait 方法時,該呼叫執行緒會被阻塞掛起,直到發生下面幾件事情之一才返回。其他執行緒呼叫了該共享物件的 notify 或者 notify 方法 其他執行緒呼叫了該執行緒的 interrupt 方法,該執行緒丟擲 interruptedexception 異常返回。注...

執行緒之間協作 等待與通知

在理解了執行緒之間可能存在相互衝突,以及怎樣避免衝突之後,下一步就是學習怎樣使線 程之間相互協作。這種協作關鍵是通過執行緒之間的握手來進行的,這種握手可以通過 object的方法wait 和notify 來安全的實現。呼叫sleep 的時候鎖並沒有被釋放,理解這一點很重要。另一方面,wait 方法的...

03 執行緒的通知notify與等待wait

wait notify notifyall 方法 wait notify notifyall 是三個定義在object類裡的方法,可以用來控制線程的狀態。這三個方法最終呼叫的都是jvm級的native方法。隨著jvm執行平台的不同可能有些許差異。public class notifyalldemo ...