溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Java項(xiàng)目中多個(gè)線程怎么查找死鎖

發(fā)布時(shí)間:2021-05-11 14:47:55 來(lái)源:億速云 閱讀:170 作者:小新 欄目:開(kāi)發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)Java項(xiàng)目中多個(gè)線程怎么查找死鎖,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

Java的特點(diǎn)有哪些

Java的特點(diǎn)有哪些 1.Java語(yǔ)言作為靜態(tài)面向?qū)ο缶幊陶Z(yǔ)言的代表,實(shí)現(xiàn)了面向?qū)ο罄碚?,允許程序員以?xún)?yōu)雅的思維方式進(jìn)行復(fù)雜的編程。 2.Java具有簡(jiǎn)單性、面向?qū)ο?、分布式、安全性、平臺(tái)獨(dú)立與可移植性、動(dòng)態(tài)性等特點(diǎn)。 3.使用Java可以編寫(xiě)桌面應(yīng)用程序、Web應(yīng)用程序、分布式系統(tǒng)和嵌入式系統(tǒng)應(yīng)用程序等。

當(dāng)項(xiàng)目中有多個(gè)線程,如何查找死鎖?

1.編譯環(huán)境

IDEA 2020 ,windows10, jdk8及以上版本

一、死鎖是什么?

死鎖指A線程想使用資源但是被B線程占用了,B線程線程想使用資源被A線程占用了,導(dǎo)致程序無(wú)法繼續(xù)下去了。

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();
    }
}

Java項(xiàng)目中多個(gè)線程怎么查找死鎖

1.2 死鎖的例子;

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

二、使用jdk內(nèi)置工具檢測(cè)死鎖

方法一. jconsole.exe

進(jìn)入你的jdk安裝路徑中,打開(kāi)jdk/bin/jconsole.exe
使用步驟如下:

Java項(xiàng)目中多個(gè)線程怎么查找死鎖

Java項(xiàng)目中多個(gè)線程怎么查找死鎖

Java項(xiàng)目中多個(gè)線程怎么查找死鎖

檢測(cè)結(jié)果:

Java項(xiàng)目中多個(gè)線程怎么查找死鎖

方法二. jvisualvm.exe

進(jìn)入你的jdk安裝路徑中,打開(kāi)jdk/bin/jvisualvm.exe
優(yōu)點(diǎn):比較細(xì),比較全面
缺點(diǎn):加載有點(diǎn)慢!
使用步驟如下:

Java項(xiàng)目中多個(gè)線程怎么查找死鎖

Java項(xiàng)目中多個(gè)線程怎么查找死鎖

可以在里面看到是該項(xiàng)目代碼的第39行出現(xiàn)了死鎖。

方法三. jmc.exe

進(jìn)入你的jdk安裝路徑中,打開(kāi)jdk/bin/jmc.exe
優(yōu)點(diǎn):可以對(duì)所以死鎖進(jìn)行判斷
缺點(diǎn):沒(méi)有給出解決方法
使用步驟如下:

Java項(xiàng)目中多個(gè)線程怎么查找死鎖

三、死鎖解決方法

通過(guò)死鎖的形成條件來(lái)解決死鎖問(wèn)題,從根源上消除死鎖。
1.請(qǐng)求擁有條件(一個(gè)線程所持有一個(gè)資源后又試圖請(qǐng)求另一個(gè)資源)可修改
2.環(huán)路等待條件(多個(gè)線程在獲取資源時(shí)形成一個(gè)環(huán)形鏈)可修改

舉例修改: 方法:(修改環(huán)路等待條件)
//讓線程二和線程一競(jìng)爭(zhēng)同一個(gè)鎖,修改為并行,這樣避免出現(xiàn)環(huán)路

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){   //讓線程二和線程一競(jìng)爭(zhēng)同一個(gè)鎖,修改為并行,這樣避免出現(xiàn)環(huán)路
                    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項(xiàng)目中多個(gè)線程怎么查找死鎖

關(guān)于“Java項(xiàng)目中多個(gè)線程怎么查找死鎖”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI