死鎖是多進程環(huán)境下的一種假死現(xiàn)象,即產(chǎn)生死鎖的進程都處于等待狀態(tài)。只要滿足了下面四個必要條件,就有可能產(chǎn)生死鎖:
- 互斥條件:進程對所分配到的資源不允許其他進程進行訪問,若其他進程訪問該資源,只能等待,直至占有該資源的進程使用完成后釋放該資源
- 請求和保持條件:進程獲得一定的資源之后,又對其他資源發(fā)出請求,但是該資源可能被其他進程占有,此事請求阻塞,但又對自己獲得的資源保持不放
- 不可剝奪條件:是指進程已獲得的資源,在未完成使用之前,不可被剝奪,只能在使用完后自己釋放
- 環(huán)路等待條件:是指進程發(fā)生死鎖后,必然存在一個進程–資源之間的環(huán)形鏈
一旦產(chǎn)生了死鎖,程序?qū)⒉辉偻聢?zhí)行。那么應(yīng)該怎么分析程序是否產(chǎn)生了死鎖呢?本節(jié)來介紹一種使用Java Dump分析死鎖的方法。
1.包含死鎖的程序
下面是一段包含死鎖的程序:DeadLock.java
public class DeadLock {
final Object lockA = new Object();
final Object lockB = new Object();
public static void main(String[] args) {
DeadLock demo = new DeadLock();
demo.startLock();
}
public void startLock(){
ThreadA a= new ThreadA(lockA,lockB);
ThreadB b= new ThreadB(lockA,lockB);
//start threads
a.start();
b.start();
}
}
class ThreadA extends Thread{
private Object lockA = null;
private Object lockB = null;
public ThreadA(Object a, Object b){
this.lockA = a;
this.lockB = b;
}
public void run() {
synchronized (lockA) {
System.out.println("*** Thread A: ***: Lock A" );
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockB) {
System.out.println("*** Thread A: ***: Lock B" );
}
}
System.out.println("*** Thread A: ***: Finished" );
}
}
class ThreadB extends Thread{
private Object lockA = null;
private Object lockB = null;
public ThreadB(Object a, Object b){
this.lockA = a;
this.lockB = b;
}
public void run() {
synchronized (lockB) {
System.out.println("*** Thread B: ***: Lock B" );
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockA) {
System.out.println("*** Thread B: ***: Lock A" );
}
}
System.out.println("*** Thread B: ***: Finished" );
}
}
說明:以上代碼中,有兩個共享資源lockA和lockB,同時啟動兩個線程a和b,其中線程a先申請資源lockA,然后睡3秒,再去申請資源lockB;線程b先申請資源lockB,然后也睡3秒,再去申請資源lockA。當線程a啟動并申請到資源lockA然后睡3秒時,這時線程b啟動并申請到資源lockB也睡3秒;等線程a睡醒后去申請資源lockB,發(fā)現(xiàn)資源lockB被其他線程占用,所以線程a就開始等待;等線程b睡醒后去申請資源lockA,發(fā)現(xiàn)資源lockA也被其他線程占用,然后線程b也開始等待。如此這般,a和b就進入了循環(huán)等待的死鎖狀態(tài)。
2.使用JDK的Thread Dump工具分析死鎖
這里介紹一種在Windows和Linux下,使用JDK提供的Thread Dump工具分析死鎖的辦法。
1.Windows下使用Thread Dump分析死鎖
(1)編譯并執(zhí)行DeadLock.java程序

(2)按Ctrl + Break(或者fn + b)分析死鎖


2.Linux下使用Thread Dump分析死鎖
(1)編譯并執(zhí)行DeadLock.java程序

(2)使用kill -3 PID分析死鎖
新打開一個終端,查看jps進程號,使用kill -3 PID殺死死鎖進程:

原來的終端窗口會顯示檢測到的死鎖信息:

死鎖分析是一門非常重要的技術(shù)手段。使用Thread Dump工具可以方便的檢測出程序是否包含死鎖。
本節(jié)介紹了Java中使用Thread Dump工具分析死鎖的詳細過程。祝你玩的愉快!