要避免死鎖,就要學會制造死鎖,是以要先了解下問什麼會出現死鎖。
在多線程并發條件下,多線程互相等待搶占資源。
而恰好A線程要擷取B線程持有的鎖 1,B線程要擷取A線程持久的鎖 2。如果B線程不釋放鎖,A線程則永遠擷取不到,但B線程先要釋放鎖,就必須先拿到A線程持久的鎖,這豈不是很繞。這就是代碼中和資料庫中很常見的死鎖。下面用java寫一段:
package com.ws;
import org.junit.Test;
/**
* Created by wushuang
*/
public class DeadLock {
@Test
public void junitTest() {
new Thread(new Runnable() {
public void run() {
test();
}
}).start();
new Thread(new Runnable() {
public void run() {
test();
}
}).start();
}
A a = new A(); //公用對象 作為被搶占的鎖對象存在
B b = new B();
public void test() {
int i = 0;
while (true) {
System.out.println("ThreadName " + Thread.currentThread().getName());
if (i % 2 == 0) {
synchronized (a) {
System.out.println("【First】已 lock [A]對象 準備lock B");
synchronized (b) {
System.out.println("【First】已 lock [B]對象");
}
}
} else {
synchronized (b) {
System.out.println("【Second】已 lock [B]對象 準備lock A");
synchronized (a) {
System.out.println("【Second】已 lock [A]對象");
}
}
}
i += 1;
}
}
}
輸出結果如下:
可以看到兩個線程發生死鎖,Thread-0 lock了B 準備擷取A,而此時Thread-1 lock了A 準備擷取B,互相等待,導緻死鎖(至于A B是什麼不重要,他們可以代表兩個資源或者兩把鎖)