java notify和notifyAll的區別

首先從名字可以瞭解,notify是通知一個線程獲取鎖,notifyAll是通知所有相關的線程去競爭鎖。

notify不能保證獲得鎖的線程,真正需要鎖,並且可能產生死鎖。

舉例1:

所有人(消費者線程)準備吃飯,食堂沒有開放(沒有釋放鎖)打飯窗口(鎖),所有人等待(WAITING)。

食堂開飯打飯窗口(釋放鎖),並廣播消息“開飯了”(notifyAll),所有人競爭排隊,並等待吃飯(BLOCKED)。每一個人依次在打飯窗口(獲得鎖)打飯(RUNNABLE)。如果想吃飯就打完飯後離開(釋放鎖),不想吃飯就直接離開(釋放鎖)。如果吃完了還想吃,就主動等待下一次“開飯了”的消息(wait)。

食堂通知一個人來吃飯(notify),此人來到打飯窗口(獲得鎖)打飯(RUNNABLE),其他人都在等待開飯的消息(WAITING)。如果想吃飯就打完飯後離開(釋放鎖),不想吃飯就直接離開(釋放鎖)。如果吃完了還想吃,就主動等待下一次“開飯”的消息(WAITING)。
notify不能保證通知到真正想吃飯的人。

 

舉例2:

兩個生產者P1、P2,兩個消費者C1、C2,共同操作一個隊列,隊列最大長度爲1。

開始P1、P2、C1、C2都處於運行狀態(RUNNABLE)。

C1先獲得鎖,P1、P2、C2爲BLOCKED狀態。C1發現隊列爲空,主動進入WAITING。C2接着獲得鎖,成爲RUNNABLE狀態,發現隊列爲空,主動進入WAITING。

P1接着獲得鎖,成爲RUNNABLE狀態,在隊列中插入一個元素,notify到了另一個生產者P2。P1循環生產,發現隊列不爲空,成爲WAITING。

P2成爲RUNNABLE狀態,發現隊列有值,主動進入WAITING。

此時鎖已被釋放,但P1、P2、C1、C2都處於WAITING狀態,沒有線程去獲取鎖,死了。

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