活躍性危險 一、死鎖 發生:每個人都不願意放棄自己的鎖,確想要別人的鎖,這就會導致死鎖 1.鎖順序死鎖:如果每個線程以固定的順序獲取鎖,那麼至少在程式中不會出現鎖順序導致的死鎖; 因為順序固定如:所有線程:A-B-C 則無問題,如果一個A-B B-A則會發生死鎖 例子1:簡單死鎖 例子2:轉賬死鎖 ...
活躍性危險
一、死鎖
發生:每個人都不願意放棄自己的鎖,確想要別人的鎖,這就會導致死鎖
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.活鎖
不會阻塞線程,但是也不能繼續執行
類似於程式不斷嘗試不斷失敗,永遠無法跳出來