wait, notify 和 notifyAll區別

作用

java使用wait(),notify(),notifyAll()來進行線程之間的通訊

共同點:

都是Java Object對象裏面的方法:
wait()方法:如果對象調用了wait方法就會使持有該對象的線程把該對象的控制權交出去,然後處於等待狀態。
notify()方法:如果對象調用了notify方法就會通知某個正在等待這個對象的控制權的線程可以繼續運行。
notifyAll()方法:如果對象調用了notifyAll方法就會通知所有等待這個對象控制權的線程繼續運行。

wait方法:

1.該方法用來將當前線程置入休眠狀態,同時釋放掉當前對象的鎖,在調用wait之前,線程必須要獲得該對象的對象鎖。
2.由於需要獲得對象鎖才能使用wait()方法,說明調用wait()方法必須在sychronized{}代碼塊或者synchroniezd方法中。調用wait()釋放了當前對象的鎖。其他線程就有可能進入到synchronized方法。
3.如果調用wait()時,沒有持有適當的鎖,則拋出IllegalMonitorStateException,它是RuntimeException的一個子類,因此,不需要try-catch結構。
4.wait()醒來之後執行wait()後面一句代碼,依次從後面執行

notify方法

1.方法調用之前由於也需要獲取該對象的鎖,所以使用的位置: synchronized方法中或者synchronized代碼塊中。
2.通知那些可能等待該對象的對象鎖的其他線程。如果有多個線程等待,則線程規劃器任意挑選出其中一個wait()狀態的線程來發出通知,並使它等待獲取該對象的對象鎖(notify後,當前線程不會馬上釋放該對象鎖,wait所在的線程並不能馬上獲取該對象鎖,要等到程序退出synchronized代碼塊後,當前線程纔會釋放鎖,wait所在的線程也纔可以獲取該對象鎖
3.wait()方法執行完畢之後,會立刻釋放掉鎖,如果沒有再次使用notify,其他wait()的線程由於沒有得到通知,會繼續阻塞在wait()的狀態,等待其他對象調用notify或者notifyAll來喚醒。

notifyAll方法

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

wait(long)和wait(long,int)

設置等待超時時間的,對於wait(long),如果在等待線程超過了設置的時間,則需要通過競爭重新獲取鎖。另外,需要知道,如果設置了超時時間,當wait()返回時,我們不能確定它是因爲接到了通知還是因爲超時而返回的,因爲wait()方法不會返回任何相關的信息。但一般可以通過設置標誌位來判斷,在notify之前改變標誌位的值,在wait()方法後讀取該標誌位的值來判斷,當然爲了保證notify不被遺漏,我們還需要另外一個標誌位來循環判斷是否調用wait()方法。

總結:

1.如果線程調用了wait方法,那麼線程進入線程池處於等待狀態
2.notifyAll喚醒所有的線程,notify隨機喚醒一個。notify喚醒的是任意一個線程。當前notify的線程,是隨機被執行的。notify()調用的地方也是synchronized代碼塊或者synchronized方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章