notify發生死鎖的情景

2021-06-20 21:51:53 字數 2758 閱讀 2648

jvm多個執行緒間的通訊是通過 執行緒的鎖、條件語句、以及wait()、notify()/notifyall組成。

下面來實現乙個啟用多個執行緒來迴圈的輸出兩個不同的語句:

package

com.tyxh.block;

class

outturn

system.

out.println(

"sub ---- "

+count

);issub

=false

;

this

.notify();

}  

catch

(exception e)

count

++;}

public

synchronized

void

main()

system.

out.println(

"main (((((((((((( "

+count

);issub

=true

;

this

.notify();

}  

catch

(exception e)

count

++;}

}

package

com.tyxh.block;

public

class

lockdemo catch (interruptedexception e)

for

(int

i = 0; i < 5; i++)

}

}).start();

new

thread(

new

runnable() catch (interruptedexception e)

for

(int

i = 0; i < 5; i++)

}

}).start();

}

}

}

解釋一下原因:

outturn類中的sub和main方法都是同步方法,所以多個呼叫sub和main方法的執行緒都會處於阻塞狀態,等待乙個正在執行的執行緒來喚醒它們。下面分別分析一下使用notify和notifyall方法喚醒執行緒的不同之處:

上面的**使用了notify方法進行喚醒,而notify方法只能喚醒乙個執行緒,其它等待的執行緒仍然處於wait狀態,假設呼叫sub方法的執行緒執行完後(即

system.

out.println(

"sub ---- "

+ count

) 執行完之後),所有的執行緒都處於等待狀態,此時在sub方法中的執行緒執行了issub=false語句後又執行了notify方法,這時如果喚醒的是乙個sub方法的排程執行緒,那麼while迴圈等於true,則此喚醒的執行緒也會處於等待狀態,此時所有的執行緒都處於等待狀態,那麼也就沒有了執行的執行緒來喚醒它們,這就發生了死鎖。

如果使用notifyall方法來喚醒所有正在等待該鎖的執行緒,那麼所有的執行緒都會處於執行前的準備狀態(就是sub方法執行完後,喚醒了所有等待該鎖的狀態,注:不是wait狀態),那麼此時,即使再次喚醒乙個sub方法排程執行緒,while迴圈等於true,喚醒的執行緒再次處於等待狀態,那麼還會有其它的執行緒可以獲得鎖,進入執行狀態。

總結:notify方法很容易引起死鎖,除非你根據自己的程式設計,確定不會發生死鎖,notifyall方法則是執行緒的安全喚醒方法。

附:notify和notifyall的區別:

notify()和notifyall()都是object物件用於通知處在等待該物件的執行緒的方法。

void notify(): 喚醒乙個正在等待該物件的執行緒。

void notifyall(): 喚醒所有正在等待該物件的執行緒。

兩者的最大區別在於:

notifyall使所有原來在該物件上等待被notify的執行緒統統退出wait的狀態,變成等待該物件上的鎖,一旦該物件被解鎖,他們就會去競爭。

notify他只是選擇乙個wait狀態執行緒進行通知,並使它獲得該物件上的鎖,但不驚動其他同樣在等待被該物件notify的執行緒們,當第乙個執行緒執行完畢以後釋放物件上的鎖,此時如果該物件沒有再次使用notify語句,即便該物件已經空閒,其他wait狀態等待的執行緒由於沒有得到該物件的通知,繼續處在wait狀態,直到這個物件發出乙個notify或notifyall,它們等待的是被notify或notifyall,而不是鎖。

**來自於:網友

gordon_yangyibao

notify發生死鎖的情景

jvm多個執行緒間的通訊是通過 執行緒的鎖 條件語句 以及wait notify notifyall組成。下面來實現乙個啟用多個執行緒來迴圈的輸出兩個不同的語句 package com.tyxh.block class outturn system.out.println sub count iss...

SVN發生死鎖解決

今天在修改專案檔案時,與另外乙個同事發生了同步衝突,我在不知道他已經提交過的情況下,對舊檔案進行修改然後提交,發生了死鎖問題。注 因檔案版本不同而提交衝突時,小概率會發生死鎖 previous operation has not finished run cleanup if it was inte...

mysql產生死鎖 MySQL會發生死鎖嗎?

mysql的innodb引擎事務有4種隔離級別,主要是為了保證資料的一致性。innodb引擎提供了行級鎖,表鎖。myisam提供了表鎖,如題,mysql會發生死鎖嗎?答會,在innodb引擎下,rr repeatable read 級別,如果多個事務爭搶同乙個資源,會發生死鎖。在rr級別下,mysq...