標籤:bit dead 提交 編程 固定 無法 div ram 阻塞
活躍性危險一、死結
發生:每個人都不願意放棄自己的鎖,確想要別人的鎖,這就會導致死結
1.鎖順序死結:如果每個線程以固定的順序擷取鎖,那麼至少在程式中不會出現鎖順序導致的死結;
因為順序固定如:所有線程:A-B-C 則無問題,如果一個A-B B-A則會發生死結
例子1:簡單死結
public class LeftRightDeadlock { private final Object left = new Object(); private final Object right = new Object(); public void leftRight() { synchronized (left) { //鎖住left synchronized (right) { //鎖住right doSomething(); } } } //如果一個線程進入上面方法鎖住 left,另一個線程進入下面方法鎖住right,則會產生互相等待 而死結 public void rightLeft() { synchronized (right) { //鎖住right synchronized (left) { //鎖住left doSomethingElse(); } } } void doSomething() { } void doSomethingElse() { }}
例子2:轉賬死結
public static void transferMoney(Account fromAccount,Account toAccount,DollarAmount amount) throws InsufficientFundsException { //轉賬 a-b 和 b-a ,如果同時發生,則有可能發生死結;這種取決於參數的傳入;並不是能夠完全的判斷得到 synchronized (fromAccount) { synchronized (toAccount) { if (fromAccount.getBalance().compareTo(amount) < 0) throw new InsufficientFundsException(); else { fromAccount.debit(amount); toAccount.credit(amount); } } } }
2.資源死結
同時擷取資源,而資源卻相互被鎖住,就會產生死結;
如:一個應用有兩個資料庫,剛好兩個線程進入兩個串連池,兩個串連池都滿了,則需要相互等待對方釋放串連
線程饑餓死結:表現為線程池不夠,線程池內的線程相互等待(A提交B到單線程池,右提交C到單線程池,但是B要等待C完成才能執行)
3.活鎖
不會阻塞線程,但是也不能繼續執行
類似於程式不斷嘗試不斷失敗,永遠無法跳出來
java並發編程(3)避免活躍性危險