Java死鎖分析

死鎖是多進程環(huán)境下的一種假死現(xiàn)象,即產(chǎn)生死鎖的進程都處于等待狀態(tài)。只要滿足了下面四個必要條件,就有可能產(chǎn)生死鎖:

  1. 互斥條件:進程對所分配到的資源不允許其他進程進行訪問,若其他進程訪問該資源,只能等待,直至占有該資源的進程使用完成后釋放該資源
  2. 請求和保持條件:進程獲得一定的資源之后,又對其他資源發(fā)出請求,但是該資源可能被其他進程占有,此事請求阻塞,但又對自己獲得的資源保持不放
  3. 不可剝奪條件:是指進程已獲得的資源,在未完成使用之前,不可被剝奪,只能在使用完后自己釋放
  4. 環(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程序

image

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

image
image

2.Linux下使用Thread Dump分析死鎖

(1)編譯并執(zhí)行DeadLock.java程序

image

(2)使用kill -3 PID分析死鎖

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

image

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

image

死鎖分析是一門非常重要的技術(shù)手段。使用Thread Dump工具可以方便的檢測出程序是否包含死鎖。

本節(jié)介紹了Java中使用Thread Dump工具分析死鎖的詳細過程。祝你玩的愉快!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 什么是死鎖? 死鎖是一種特定的程序狀態(tài),在實體之間,由于循環(huán)依賴導(dǎo)致彼此一直處于等待之中,沒有任何個體可以繼續(xù)前進...
    小母牛不生產(chǎn)奶閱讀 243評論 0 0
  • 一、死鎖的定義 多線程以及多進程改善了系統(tǒng)資源的利用率并提高了系統(tǒng) 的處理能力。然而,并發(fā)執(zhí)行也帶來了新的問題——...
    菜菜愛吃菜呀閱讀 777評論 0 2
  • 本文主要講了java中多線程的使用方法、線程同步、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等。 首先講...
    李欣陽閱讀 2,597評論 1 15
  • Java多線程學(xué)習(xí) [-] 一擴展javalangThread類 二實現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 3,107評論 1 18
  • 在之前的課程中,我們已經(jīng)學(xué)習(xí)了進程相關(guān)的知識。進程是計算機程序被執(zhí)行的一個實例(instance),一個進程可能由...
    夏威夷的芒果閱讀 1,055評論 0 2

友情鏈接更多精彩內(nèi)容