當前位置:首頁>職場>面試死亡問題有哪些(面試官什么是死鎖)
發布時間:2024-01-19閱讀(12)
目錄
什么是死鎖?
死鎖產生原因?
如何使用IDEA查看程序是否產生死鎖?
如何避免死鎖?
什么是死鎖?
死鎖是一種非常嚴重的bug,是說多個線程同時被阻塞,線程中的一個或者多個又或者全部都在等待某個資源被釋放,造成線程無限期的阻塞,導致程序不能正常終止
?為了進一步說明死鎖,有哲學家就餐這樣的一個問題:
有一個桌子,哲學家們圍成一圈,每兩個哲學家中間有一支筷子

哲學家只能兩件事:思考或者吃飯,思考時候就不會動筷子,吃飯時會拿起左右手旁邊的筷子(先拿左后拿右)

如果有一個哲學家想吃飯,但是筷子被占用,就得等別人吃完進入思考后,才能獲得筷子,等待的過程稱為阻塞等待

在等待的情形中,會出現下面這樣一種情況:所有人都處于等待筷子中,即所有哲學家都獲取到左邊的筷子,一直獲取不到右邊的筷子,這種情況稱為死鎖

死鎖產生原因?
結合上述哲學家的例子,說明死鎖產生的四個必要條件:
互斥使用:當資源被一個線程使用或者占用時,別的線程不能使用該資源
不可搶占:獲取資源的一方,不能從正在使用資源的一方搶占掠奪資源,資源只能被使用者主動釋放
請求和保持:資源請求者在請求別的資源時,同時保持對已有資源的占有
循環等待:即p1占有p2的資源,p2占有p3的資源,p3占有p1的資源,這樣形成了一個等待環路
上述這四個條件滿足即造成的結果就是死鎖
?看這樣的一段可能產生死鎖的代碼:
public class DeadLock {public static void main(String[] args) {Object lock1 = new Object();Object lock2 = new Object();Thread t1 = new Thread(){@Overridepublic void run() {try {synchronized (lock1){Thread.sleep(1000);synchronized (lock2){System.out.println("輸出t1");}}} catch (InterruptedException e) {e.printStackTrace();}}};Thread t2 = new Thread(){@Overridepublic void run() {try {synchronized (lock2){Thread.sleep(1000);synchronized (lock1){System.out.println("輸出t2");}}} catch (InterruptedException e) {e.printStackTrace();}}};t1.start();t2.start();}}
??說明:
t1先申請lock1,lock2,釋放lock2,lock1
t2后申請lock2,lock1,釋放lock1,lock2
這種情況不會產生死鎖
t2先申請lock2,lock1,釋放lock1,lock2
t1后申請lock1,lock2,釋放lock2,lock1
這種情況也不會產生死鎖
t1申請到lock1,t2申請到lock2,這樣t1就申請不到lock2,t2就申請不到lock1,都等著對方釋放資源,這樣就產生了死鎖
因為讓t1,t2申請第一個鎖的時候都等待了1秒,所以產生死鎖的概率接近100%
運行結果:沒有執行輸出,產生死鎖

如何使用IDEA查看程序是否產生死鎖?
第一步:點擊下方紅圈內的Terminal

第二步:在下方命令窗口輸入jconsole,然后回車

第三步:雙擊發生死鎖對應的類

第四步:切換到線程,點擊下面的檢查死鎖

第五步:即可看到發生死鎖的線程

如何避免死鎖?
死鎖的產生必須滿足互斥使用,不可搶占,請求和保持,循環等待這四個條件,但是只要破壞其中任意一個條件即可破壞死鎖,其中最容易破壞的就是循環等待這個條件,那么如何破壞循環等待這個條件呢?
多個線程約定好一定的順序,按照這個順序加鎖釋放鎖
?對上述產生死鎖的代碼改造:將加鎖順序都改為lock1,lock2,看看打印結果
public class DeadLock {public static void main(String[] args) {Object lock1 = new Object();Object lock2 = new Object();Thread t1 = new Thread(){@Overridepublic void run() {try {synchronized (lock1){Thread.sleep(1000);synchronized (lock2){System.out.println("輸出t1");}}} catch (InterruptedException e) {e.printStackTrace();}}};Thread t2 = new Thread(){@Overridepublic void run() {try {synchronized (lock1){Thread.sleep(1000);synchronized (lock2){System.out.println("輸出t2");}}} catch (InterruptedException e) {e.printStackTrace();}}};t1.start();t2.start();}}
打印結果:可以看到結果可以正常輸出而不產生死鎖

小伙伴們有興趣想了解內容和更多相關學習資料的請點贊收藏 評論轉發 關注我,后面會有很多干貨。我有一些面試題、架構、設計類資料可以說是程序員面試必備!所有資料都整理到網盤了,需要的話歡迎下載!私信我回復【111】即可免費獲取

版權聲明:本文為CSDN博主「Java猿~」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_58710208/article/details/124131865
Copyright ? 2024 有趣生活 All Rights Reserve吉ICP備19000289號-5 TXT地圖HTML地圖XML地圖