Java項目有中多個線程如何查找死鎖

當項目有中多個線程,如何查找死鎖?

最近,在IDEA上進行多線程編程中老是在給線程加鎖的時候,總是會遇到死鎖問題,而當程序出現死鎖問題時,編譯器不能精確的顯示錯誤的精確位置。當項目代碼很多的時候, 往往會給自己添加不必要的麻煩,今天,我就分享分享幾個解決方法。

1.編譯環境

IDEA 2020 ,windows10, jdk8及以上版本

一、死鎖是什麼?

死鎖指A線程想使用資源但是被B線程占用瞭,B線程線程想使用資源被A線程占用瞭,導致程序無法繼續下去瞭。

1.1 死鎖的例子;

public class Deadlock {
    public static void main(String[] args) {
        Object lock1 = new Object();
        Object lock2 = new Object();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock1){
                    System.out.println("線程一得到瞭lock1");
                    try{
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("線程一獲取lock2");
                    synchronized (lock2){
                        System.out.println("線程一得到瞭lock2");
                    }
                }
            }
        });
        thread1.start();


        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock2){
                    System.out.println("線程二得到瞭lock2");
                    try{
                        //讓線程2,獲取鎖1
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("線程二獲取lock1");
                    //嘗試獲取lock1
                    synchronized (lock1){
                        System.out.println("線程二得到瞭lock1");
                    }
                }
            }
        });
        thread2.start();
    }
}

在這裡插入圖片描述

1.2 死鎖的例子;

形成死鎖的條件:
1.互斥條件:(當一個資源被一個線程擁有,當被一個線程擁有後就不能被其他線程所持有)
2.請求擁有條件(一個線程所持有一個資源後又試圖請求另一個資源)可修改
3.不可剝奪性:(一個資源被一個線程擁有之後,如果這個線程不釋放此資源,那麼其他線程不能強制獲得此資源)
4.環路等待條件(多個線程在獲取資源時形成一個環形鏈)可修改

二、使用jdk內置工具檢測死鎖

方法一. jconsole.exe

進入你的jdk安裝路徑中,打開jdk/bin/jconsole.exe
使用步驟如下:

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

檢測結果:

在這裡插入圖片描述

方法二. jvisualvm.exe

進入你的jdk安裝路徑中,打開jdk/bin/jvisualvm.exe
優點:比較細,比較全面
缺點:加載有點慢!
使用步驟如下:

在這裡插入圖片描述

在這裡插入圖片描述

可以在裡面看到是該項目代碼的第39行出現瞭死鎖。

方法三. jmc.exe

進入你的jdk安裝路徑中,打開jdk/bin/jmc.exe
優點:可以對所以死鎖進行判斷
缺點:沒有給出解決方法
使用步驟如下:

在這裡插入圖片描述

三、死鎖解決方法

通過死鎖的形成條件來解決死鎖問題,從根源上消除死鎖。
1.請求擁有條件(一個線程所持有一個資源後又試圖請求另一個資源)可修改
2.環路等待條件(多個線程在獲取資源時形成一個環形鏈)可修改

舉例修改: 方法:(修改環路等待條件)
//讓線程二和線程一競爭同一個鎖,修改為並行,這樣避免出現環路

public class Deadlock {
    public static void main(String[] args) {
        Object lock1 = new Object();
        Object lock2 = new Object();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock1){
                    System.out.println("線程一得到瞭lock1");
                    try{
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("線程一獲取lock2");
                    synchronized (lock2){
                        System.out.println("線程一得到瞭lock2");
                    }
                }
            }
        });
        thread1.start();


        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock1){   //讓線程二和線程一競爭同一個鎖,修改為並行,這樣避免出現環路
                    System.out.println("線程二得到瞭lock1"); 
                    try{
                        //讓線程2,獲取鎖1
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("線程二獲取lock1");
                    //嘗試獲取lock1
                    synchronized (lock2){
                        System.out.println("線程二得到瞭lock2");
                    }
                }
            }
        });
        thread2.start();

    }
}

在這裡插入圖片描述

四、總結

到此這篇關於Java項目有中多個線程如何查找死鎖的文章就介紹到這瞭,更多相關Java多線程查找死鎖內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: