什麼是執行緒死鎖 如何解決 (螞蟻金服面試題)

2022-08-19 06:12:15 字數 2628 閱讀 4682

認識執行緒死鎖

多個執行緒同時被阻塞,它們中的乙個或者全部都在等待某個資源被釋放。由於執行緒被無限期地阻塞,因此程式不可能正常終止。

如下圖所示,執行緒 a 持有資源 2,執行緒 b 持有資源 1,他們同時都想申請對方的資源,所以這兩個執行緒就會互相等待而進入死鎖狀態。

死鎖示意圖

下面通過乙個例子來說明執行緒死鎖,**模擬了上圖的死鎖的情況 (****於《併發程式設計之美》):

1

public

class

deadlockdemo catch

(interruptedexception e)

14 system.out.println(thread.currentthread() + "waiting get resource2");

15synchronized

(resource2) 18}

19 }, "執行緒 1").start();

2021

new thread(() -> catch

(interruptedexception e)

29 system.out.println(thread.currentthread() + "waiting get resource1");

30synchronized

(resource1) 33}

34 }, "執行緒 2").start();35}

36 }

output

1 thread[執行緒 1,5,main]get resource1

2 thread[執行緒 2,5,main]get resource2

3 thread[執行緒 1,5,main]waiting get resource2

4 thread[執行緒 2,5,main]waiting get resource1

執行緒 a 通過synchronized (resource1)獲得 resource1 的監視器鎖,然後通過thread.sleep(1000);讓執行緒 a 休眠 1s 為的是讓執行緒 b 得到執行然後獲取到 resource2 的監視器鎖。執行緒 a 和執行緒 b 休眠結束了都開始企圖請求獲取對方的資源,然後這兩個執行緒就會陷入互相等待的狀態,這也就產生了死鎖。上面的例子符合產生死鎖的四個必要條件。

學過作業系統的朋友都知道產生死鎖必須具備以下四個條件:

互斥條件:該資源任意乙個時刻只由乙個執行緒占用。

請求與保持條件:乙個程序因請求資源而阻塞時,對已獲得的資源保持不放。

不剝奪條件:執行緒已獲得的資源在末使用完之前不能被其他執行緒強行剝奪,只有自己使用完畢後才釋放資源。

迴圈等待條件:若干程序之間形成一種頭尾相接的迴圈等待資源關係。

如何避免執行緒死鎖?

破壞互斥條件

這個條件我們沒有辦法破壞,因為我們用鎖本來就是想讓他們互斥的(臨界資源需要互斥訪問)。

破壞請求與保持條件

一次性申請所有的資源。

破壞不剝奪條件

占用部分資源的執行緒進一步申請其他資源時,如果申請不到,可以主動釋放它占有的資源。

破壞迴圈等待條件

靠按序申請資源來預防。按某一順序申請資源,釋放資源則反序釋放。破壞迴圈等待條件。

我們對執行緒 2 的**修改成下面這樣就不會產生死鎖了。

1

new thread(() -> catch

(interruptedexception e)

9 system.out.println(thread.currentthread() + "waiting get resource2");

10synchronized

(resource2) 13}

14 }, "執行緒 2").start();

output

1 thread[執行緒 1,5,main]get resource1

2 thread[執行緒 1,5,main]waiting get resource2

3 thread[執行緒 1,5,main]get resource2

4 thread[執行緒 2,5,main]get resource1

5 thread[執行緒 2,5,main]waiting get resource2

6 thread[執行緒 2,5,main]get resource2

78 process finished with exit code 0

我們分析一下上面的**為什麼避免了死鎖的發生?

執行緒 1 首先獲得到 resource1 的監視器鎖,這時候執行緒 2 就獲取不到了。然後執行緒 1 再去獲取 resource2 的監視器鎖,可以獲取到。然後執行緒 1 釋放了對 resource1、resource2 的監視器鎖的占用,執行緒 2 獲取到就可以執行了。這樣就破壞了破壞迴圈等待條件,因此避免了死鎖。

什麼是死鎖?如何解決死鎖?

死鎖是指兩個或兩個以上的程序在執行過程中,由於競爭資源或者由於彼此通訊而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。產生死鎖的原因,主要包括 如果系統資源充足,程序的資源請求都能夠得到滿足,那麼死鎖出現的可能...

什麼是程序死鎖,如何解決?

所謂死鎖 是指兩個或兩個以上的程序在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。由於資源占用是互斥的,當某個程序提出申請資源後,使得有關程序在無外力協助下,永遠分配不到必需的資源而...

什麼是執行緒死鎖 如何避免死鎖

執行緒死鎖描述的是這樣一種情況 多個執行緒同時被阻塞,它們中的乙個或者全部都在等待某個資源被釋放。由於執行緒被無限期地阻塞,因此程式不可能正常終止。如下圖所示,執行緒 a 持有資源 2,執行緒 b 持有資源 1,他們同時都想申請對方的資源,所以這兩個執行緒就會互相等待而進入死鎖狀態。1.產生死鎖的四...