在多執行緒程式設計中,除了要解決資料訪問的同步與互斥之外,還需要解決的重要問題就是多執行緒的死鎖問題
。所謂死鎖: 是指兩個或兩個以上的程序
(執行緒)
在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外部處理作用,它們都將無限等待下去。
死鎖形成的原因:
系統資源不足
程序(執行緒)推進的順序不恰當;
資源分配不當
死鎖形成的條件:
互斥條件:所謂互斥就是程序在某一時間內獨佔資源。
請求與保持條件:乙個程序因請求資源而阻塞時,對已獲得的資源保持不放。
不剝奪條件:程序已獲得資源,在末使用完之前,不能強行剝奪。
迴圈等待條件:若干程序之間形成一種頭尾相接的迴圈等待資源關係。
二、死鎖例項
//1.沒有釋放鎖
void a()
mutex.unlock();
return;
} //由於在if的執行體內直接retun,而沒有呼叫unlock,導致另乙個執行緒再呼叫a方法就出現死鎖。又或者執行緒直接忘記釋放鎖也會引起死鎖
//2.單執行緒重複申請鎖
void a()
void b()
//3.雙線程多鎖申請順序不當
void thread1()
void thread2()
//申請所沒有按照順序引起死鎖
//4.迴圈鎖申請
/* 多個執行緒申請鎖的順序形成相互依賴的環形:
* a - b
* | |
* c - d
*/
假設有a、b、c、d四個人在一起吃飯,每個人左右各有乙隻筷子。所以,這其中要是有乙個人想吃飯,
他必須首先拿起左邊的筷子,再拿起右邊的筷子。現在,我們讓所有的人同時開始吃飯。
那麼就很有可能出現這種情況。每個人都拿起了左邊的筷子,或者每個人都拿起了右邊的筷子,
為了吃飯,他們現在都在等另外乙隻筷子。此時每個人都想吃飯,同時每個人都不想放棄自己已經得到的一那只筷子。
所以,事實上大家都吃不了飯。
三、死鎖避免
死鎖的代價是非常大的,有時候很難檢測排查,因此需要在程式設計過程中盡可能的避免發生死鎖。程式設計中為了避免死鎖應該遵循如下策略:
(1)在編寫多執行緒程式之前,首先編寫正確的程式,然後再移植到多執行緒。
(2)時刻檢查自己寫的程式有沒有在跳出時忘記釋放鎖。
(3)如果自己的模組可能重複使用乙個鎖,建議使用巢狀鎖。
(4)對於某些鎖**,不要臨時重新編寫,建議使用庫裡面的鎖,或者自己曾經編寫的鎖。
(5)如果某項業務需要獲取多個鎖,必須保證鎖的按某種順序獲取,否則必定死鎖。
(6)編寫簡單的測試用例,驗證有沒有死鎖。
(7)編寫驗證死鎖的程式,從源頭避免死鎖。
Java死鎖及死鎖的避免
鎖是個非常有用的工具,運用場景非常多,因為它使用起來非常簡單,而且易於理解。但同時它也會帶來一些困擾,那就是可能會引起死鎖,一旦產生死鎖,就會造成系統功能不可用。1.系統資源不足 2.進行執行推進的順序不合適 3.資源分配不當 如果系統資源充足,程序的資源請求都能得到滿足,死鎖出現的可能性就很低,否...
死鎖以及避免死鎖
目錄 一 什麼是死鎖 二 產生死鎖的四個必要條件 三 避免死鎖的方法 是指兩個或兩個以上的程序在執行過程中,由於競爭資源或者由於彼此通訊而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。1.互斥 某種資源一次只允...
如何避免死鎖
如何避免死鎖 1 使用事務時,盡量縮短事務的邏輯處理過程,及早提交或回滾事務 2 設定死鎖超時引數為合理範圍,如 3分鐘 10分種 超過時間,自動放棄本次操作,避免程序懸掛 3 優化程式,檢查並避免死鎖現象出現 4 對所有的指令碼和sp都要仔細測試,在正是版本之前。5 所有的sp都要有錯誤處理 通過...