java notify和notifyAll的對比
java notify和notifyAll
首先從名字可以了解,notify是通知一個線程獲取鎖,notifyAll是通知所有相關(guān)的線程去競爭鎖。
notify不能保證獲得鎖的線程,真正需要鎖,并且可能產(chǎn)生死鎖。
舉例1:
所有人(消費者線程)準備吃飯,食堂沒有開放(沒有釋放鎖)打飯窗口(鎖),所有人等待(WAITING)。
食堂開飯打飯窗口(釋放鎖),并廣播消息“開飯了”(notifyAll),所有人競爭排隊,并等待吃飯(BLOCKED)。每一個人依次在打飯窗口(獲得鎖)打飯(RUNNABLE)。如果想吃飯就打完飯后離開(釋放鎖),不想吃飯就直接離開(釋放鎖)。如果吃完了還想吃,就主動等待下一次“開飯了”的消息(wait)。
食堂通知一個人來吃飯(notify),此人來到打飯窗口(獲得鎖)打飯(RUNNABLE),其他人都在等待開飯的消息(WAITING)。如果想吃飯就打完飯后離開(釋放鎖),不想吃飯就直接離開(釋放鎖)。如果吃完了還想吃,就主動等待下一次“開飯”的消息(WAITING)。
notify不能保證通知到真正想吃飯的人。
舉例2:
兩個生產(chǎn)者P1、P2,兩個消費者C1、C2,共同操作一個隊列,隊列最大長度為1。
開始P1、P2、C1、C2都處于運行狀態(tài)(RUNNABLE)。
C1先獲得鎖,P1、P2、C2為BLOCKED狀態(tài)。C1發(fā)現(xiàn)隊列為空,主動進入WAITING。C2接著獲得鎖,成為RUNNABLE狀態(tài),發(fā)現(xiàn)隊列為空,主動進入WAITING。
P1接著獲得鎖,成為RUNNABLE狀態(tài),在隊列中插入一個元素,notify到了另一個生產(chǎn)者P2。P1循環(huán)生產(chǎn),發(fā)現(xiàn)隊列不為空,成為WAITING。
P2成為RUNNABLE狀態(tài),發(fā)現(xiàn)隊列有值,主動進入WAITING。
此時鎖已被釋放,但P1、P2、C1、C2都處于WAITING狀態(tài),沒有線程去獲取鎖,死了。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
無感NullPointerException的值相等判斷方法
當我們需要去判斷一個?入?yún)?查庫?返回的開關(guān)變量(通常是個Integer類型的)時,常常會寫如下的if-else判斷語句。但又會為在生產(chǎn)環(huán)境看到的「NullPointerException」感到困擾,遇到這個問題如何處理呢,下面小編通過本文給大家詳細講解,需要的朋友參考下吧2023-02-02Apache?Commons?CLI構(gòu)建命令行應(yīng)用利器教程
這篇文章主要為大家介紹了構(gòu)建命令行應(yīng)用利器Apache?Commons?CLI的使用教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12Java?數(shù)據(jù)結(jié)構(gòu)與算法系列精講之隊列
這篇文章主要介紹了Java隊列數(shù)據(jù)結(jié)構(gòu)的實現(xiàn),隊列是一種特殊的線性表,只允許在表的隊頭進行刪除操作,在表的后端進行插入操作,隊列是一個有序表先進先出,想了解更多相關(guān)資料的小伙伴可以參考下面文章的詳細內(nèi)容2022-02-02Java基于控制臺界面實現(xiàn)ATM系統(tǒng)
這篇文章主要為大家詳細介紹了Java基于控制臺界面實現(xiàn)ATM系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05基于Java實現(xiàn)一個簡單的數(shù)據(jù)同步組件
這篇文章主要為大家詳細介紹了如何基于Java實現(xiàn)一個簡單的數(shù)據(jù)同步組件,文中的示例代碼講解詳細,具有一定的借鑒價值,感興趣的小伙伴可以了解一下2023-06-06