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,而不是鎖。
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...