多執行緒程式設計之執行緒死鎖問題

2021-08-14 18:40:26 字數 1315 閱讀 3866

在多執行緒程式設計中,除了要解決資料訪問的同步與互斥之外,還需要解決的重要問題就是多執行緒的死鎖問題。所謂死鎖: 是指兩個或兩個以上的程序(執行緒)在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外部處理作用,它們都將無限等待下去。

一、死鎖原因與形成條件

死鎖形成的原因:

系統資源不足

程序(執行緒)推進的順序不恰當;

資源分配不當

死鎖形成的條件:

互斥條件:所謂互斥就是程序在某一時間內獨佔資源。

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

不剝奪條件:程序已獲得資源,在末使用完之前,不能強行剝奪。

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

從程式設計經驗上來講,形成死鎖的一般原因有以下幾種:

個人使用鎖的經驗差異。

程式模組使用鎖的差異。

工程**版本之間的差異。

工程**分支之間的差異。

修改**和重構**帶來的差異。

二、常見死鎖形成的場景

死鎖形成的常見情況有以下幾種:

2.1 忘記釋放鎖

void data_process()

2.2 單執行緒重複申請鎖

void sub_func()

void data_process()

2.3 多執行緒多鎖申請

void data_process1()

void data_process2()

2.4 環形鎖申請

/* 多個執行緒申請鎖的順序形成相互依賴的環形:

* a - b

* | |

* c - d

*/

三、死鎖的避免策略

死鎖的代價是非常大的,有時候很難檢測排查,因此需要在程式設計過程中盡可能的避免發生死鎖。程式設計中為了避免死鎖應該遵循如下策略:

在編寫多執行緒程式之前,首先編寫正確的程式,然後再移植到多執行緒。

時刻檢查自己寫的程式有沒有在跳出時忘記釋放鎖。

如果自己的模組可能重複使用乙個鎖,建議使用巢狀鎖。

對於某些鎖**,不要臨時重新編寫,建議使用庫裡面的鎖,或者自己曾經編寫的鎖。

如果某項業務需要獲取多個鎖,必須保證鎖的按某種順序獲取,否則必定死鎖。

編寫簡單的測試用例,驗證有沒有死鎖。

編寫驗證死鎖的程式,從源頭避免死鎖。

多執行緒之死鎖

1 死鎖發生的場景 有時候兩個或者多個執行緒需要訪問同乙份資源,這裡就涉及到執行緒同步的問題 thread1 synchronized object1 thread2 synchronized object2 看看上面的例子,兩個執行緒各自都有想要訪問對方的想法,可是雙方都不願意放手,就像a拿到了開...

多執行緒之死鎖

死鎖。同步中巢狀同步。你有一根筷子,我有一根筷子,我要吃飯,你不給我,我不給你,誰都吃不著飯,死鎖發生,但是死鎖不一會發生,也會存在和諧的狀態,就是你把筷子給我,我吃一口,我再把筷子給你,你再吃一口 class ticket implements runnable else while true s...

多執行緒死鎖問題

死鎖是一種併發鎖定的特殊狀態,指的是,當具有多個共享資源時 一部分執行緒持有一部分資源的鎖 要求另外的執行緒持有的另外的資源的鎖 形成了各自持有各自的鎖而要求對方的鎖的狀態 這樣 進入了乙個互相等待的狀態 都無法繼續執行 則稱之為產生了死鎖 死鎖並不是一種真正的鎖,而是一種特殊狀態,會造成程式無法繼...