在多執行緒程式設計中,除了要解決資料訪問的同步與互斥之外,還需要解決的重要問題就是多執行緒的死鎖問題。所謂死鎖: 是指兩個或兩個以上的程序(執行緒)在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外部處理作用,它們都將無限等待下去。
一、死鎖原因與形成條件
死鎖形成的原因:
系統資源不足
程序(執行緒)推進的順序不恰當;
資源分配不當
死鎖形成的條件:
互斥條件:所謂互斥就是程序在某一時間內獨佔資源。
請求與保持條件:乙個程序因請求資源而阻塞時,對已獲得的資源保持不放。
不剝奪條件:程序已獲得資源,在末使用完之前,不能強行剝奪。
迴圈等待條件:若干程序之間形成一種頭尾相接的迴圈等待資源關係。
從程式設計經驗上來講,形成死鎖的一般原因有以下幾種:
個人使用鎖的經驗差異。
程式模組使用鎖的差異。
工程**版本之間的差異。
工程**分支之間的差異。
修改**和重構**帶來的差異。
二、常見死鎖形成的場景
死鎖形成的常見情況有以下幾種:
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...
多執行緒死鎖問題
死鎖是一種併發鎖定的特殊狀態,指的是,當具有多個共享資源時 一部分執行緒持有一部分資源的鎖 要求另外的執行緒持有的另外的資源的鎖 形成了各自持有各自的鎖而要求對方的鎖的狀態 這樣 進入了乙個互相等待的狀態 都無法繼續執行 則稱之為產生了死鎖 死鎖並不是一種真正的鎖,而是一種特殊狀態,會造成程式無法繼...