Java項(xiàng)目有中多個(gè)線程如何查找死鎖
當(dāng)項(xiàng)目有中多個(gè)線程,如何查找死鎖?
最近,在IDEA上進(jìn)行多線程編程中老是在給線程加鎖的時(shí)候,總是會(huì)遇到死鎖問(wèn)題,而當(dāng)程序出現(xiàn)死鎖問(wèn)題時(shí),編譯器不能精確的顯示錯(cuò)誤的精確位置。當(dāng)項(xiàng)目代碼很多的時(shí)候, 往往會(huì)給自己添加不必要的麻煩,今天,我就分享分享幾個(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();
}
}

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
使用步驟如下:



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

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


可以在里面看到是該項(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)有給出解決方法
使用步驟如下:

三、死鎖解決方法
通過(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();
}
}

四、總結(jié)
到此這篇關(guān)于Java項(xiàng)目有中多個(gè)線程如何查找死鎖的文章就介紹到這了,更多相關(guān)Java多線程查找死鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java遠(yuǎn)程調(diào)用Shell腳本并獲取輸出信息【推薦】
這篇文章主要介紹了Java遠(yuǎn)程調(diào)用Shell腳本并獲取輸出信息,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09
詳解Spring Cloud Hystrix斷路器實(shí)現(xiàn)容錯(cuò)和降級(jí)
本篇文章主要介紹了詳解Spring Cloud Hystrix斷路器實(shí)現(xiàn)容錯(cuò)和降級(jí),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
java遞歸與非遞歸實(shí)現(xiàn)掃描文件夾下所有文件
這篇文章主要為大家詳細(xì)介紹了java遞歸與非遞歸實(shí)現(xiàn)掃描文件夾下所有文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02
java關(guān)于并發(fā)模型中的兩種鎖知識(shí)點(diǎn)詳解
在本篇文章了小編給大家整理的是一篇關(guān)于java關(guān)于并發(fā)模型中的兩種鎖知識(shí)點(diǎn)詳解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2021-04-04
Spring Cloud Config Client超時(shí)及重試示例詳解
這篇文章主要給大家介紹了關(guān)于Spring Cloud Config Client超時(shí)及重試的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05
mybatisplus?@Select注解中拼寫動(dòng)態(tài)sql異常問(wèn)題的解決
這篇文章主要介紹了mybatisplus?@Select注解中拼寫動(dòng)態(tài)sql異常問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Springboot框架實(shí)現(xiàn)自動(dòng)裝配詳解
在使用springboot時(shí),很多配置我們都沒(méi)有做,都是springboot在幫我們完成,這很大一部分歸功于springboot自動(dòng)裝配。本文將詳細(xì)為大家講解SpringBoot的自動(dòng)裝配原理,需要的可以參考一下2022-08-08
JAVA浮點(diǎn)數(shù)計(jì)算精度損失底層原理與解決方案
本文主要介紹了JAVA浮點(diǎn)數(shù)計(jì)算精度損失底層原理與解決方案。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02

