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,獲取鎖1Thread.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,獲取鎖1Thread.sleep(1000); } catch (InterruptedException e) {e.printStackTrace(); } System.out.println('線程二獲取lock1'); //嘗試獲取lock1 synchronized (lock2){System.out.println('線程二得到了lock2'); }} }});thread2.start(); }}
到此這篇關(guān)于Java項(xiàng)目有中多個(gè)線程如何查找死鎖的文章就介紹到這了,更多相關(guān)Java多線程查找死鎖內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. JavaScript中常見(jiàn)的幾種獲取元素的方式2. Xml簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理3. phpstudy apache開(kāi)啟ssi使用詳解4. ASP.NET MVC使用異步Action的方法5. AJAX的跨域問(wèn)題解決方案6. jsp實(shí)現(xiàn)登錄驗(yàn)證的過(guò)濾器7. jsp文件下載功能實(shí)現(xiàn)代碼8. uni-app結(jié)合.NET 7實(shí)現(xiàn)微信小程序訂閱消息推送9. ajax實(shí)現(xiàn)頁(yè)面的局部加載10. uniapp解決軟鍵盤(pán)彈出問(wèn)題方法詳解
