Java併發編程 - 一個簡單的死鎖示例和死鎖的檢查

  Java線程死鎖是一個經典的多線程問題。由於不一樣的線程都在等待根本不可能被釋放的鎖,從而致使全部的任務都沒法繼續完成。多線程

1.死鎖程序示例

建立類 DeadLockThread:ide

public class DeadLockThread implements Runnable {

    private Object lock1 = new Object();
    private Object lock2 = new Object();

    private String s;

    public void setS(String s) {
        this.s = s;
    }

    @Override
    public void run() {
        if ("a".equalsIgnoreCase(s)) {
            synchronized (lock1) {
                System.out.println(Thread.currentThread() + " a 正在執行");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2) {
                    System.out.println("lock1 -> lock2 死鎖未生效");
                }
            }
        }
        if ("b".equalsIgnoreCase(s)) {
            synchronized (lock2) {
                System.out.println(Thread.currentThread() + " b 正在執行");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1) {
                    System.out.println("lock2 -> lock1 死鎖未生效");
                }
            }
        }
    }
}

建立運行類 Main:工具

public class Main {

    public static void main(String[] args) throws InterruptedException {
        DeadLockThread deadLockThread = new DeadLockThread();

        deadLockThread.setS("a");
        Thread threadA = new Thread(deadLockThread);
        threadA.start();
        Thread.sleep(200);

        deadLockThread.setS("b");
        Thread threadB = new Thread(deadLockThread);
        threadB.start();
        Thread.sleep(200);
    }
}

運行結果以下:性能

 2.使用JDK自帶工具作死鎖後的檢查

1.進入JDK安裝文件夾中的bin目錄,執行jps命令:測試

 獲得正在運行着的線程Main的id值是12295。ui

2.在執行 jstack -l 12295 命令,查看結果:this

由此結果可知,程序有死鎖的現象。idea

3.使用IDEA的FindBugs插件檢查可能出現的死鎖

右鍵測試代碼所在的包,選擇分析包內文件spa

 分析結果以下:插件

This method calls Thread.sleep() with a lock held. 
This may result in very poor performance and scalability, or a deadlock, since other threads may be waiting to acquire the lock. 
It is a much better idea to call wait() on the lock, which releases the lock and allows other threads to run.
此方法調用thread.sleep(),並保留一個鎖。
這可能會致使性能和可伸縮性很是差,或者出現死鎖,由於其餘線程可能正在等待獲取鎖。
最好對鎖調用wait(),這樣能夠釋放鎖並容許其餘線程運行。

 

 

死鎖是程序設計的bug,在設計程序時要避免雙方互相持有對方鎖的狀況。須要說明的是,本實驗使用synchronized嵌套的代碼結構來實現死鎖,其實不使用嵌套的synchronized代碼結構也會出現死鎖,與嵌套不嵌套沒有任何的關係。只要互相等待對方釋放鎖,就有可能出現死鎖。

相關文章
相關標籤/搜索