經典的「哲學家進餐」問題就很好的描述了死鎖的狀況;
死鎖的成因:如果每個人都擁有其他人需要的資源,但是同時又等待其他人已經擁有的資源,並且每個人在獲取所有需要的資源之前都不會放棄已經擁有的資源;
發生死鎖的原因:兩個執行緒試圖以不同的順序來獲得相同的鎖。
解決辦法:如果按照相同的順序請求鎖,那麼就不會出現迴圈的加鎖依賴性,因此就不會產生死鎖。如果每個需要鎖l和鎖m的執行緒都以相同的順序獲取l和m鎖,那麼就不會發生死鎖了;
發生死鎖的原因:當獲取鎖的順序取決於引數的傳入順序時,那麼就沒法保證死鎖不會發生。
解決辦法:必須定義鎖的順序,並在整個應用程式中按照這個順序來獲取鎖;
例如:可以使用system.identityhashcode來比較引數的hash值的大小,以此來作為獲取鎖的順序;
發生死鎖的原因:在持有鎖的情況下呼叫某個外部方法,那麼將出現活躍性問題。在這個外部方法中可能會獲取其他鎖,或者阻塞時間過長,導致其他執行緒無法及時獲取當前被持有的鎖;
解決方法:採用開發式呼叫,即在呼叫外部方法時,不持有鎖;
發生死鎖的原因:有界線程池/資源池與相互依賴的任務一起使用;
例如:乙個任務提交另外乙個任務,並且等待被提交任務在單執行緒的executor中執行完成。這種情況下,第乙個任務就會永遠等待下去,並使得另外乙個任務以及在這個executor中執行的所有其他任務都停止執行。
解決辦法:通過使用無界線程池;
概念:執行緒將不斷重複執行相同的操作,而且總是會失敗。該問題儘管不會阻塞執行緒,但是也不能繼續執行下去。
例如:在處理事務訊息的應用中:如果不能成功的處理某個訊息,那麼訊息處理機制將回滾整個事務,並將它重新放到佇列的開頭。如果訊息處理器在處理某種特定型別的訊息時存在錯誤並導致它失敗,那麼每當這個訊息從佇列中取出並傳遞到存在錯誤的處理器時,都會發生事務回滾。
解決方法:在併發應用中,通過等待隨機長度時間和回退可以有效的避免活鎖的發生;
8 多執行緒 避免活躍性危險
一.死鎖 經典的 哲學家進餐 問題很好地描述了死鎖狀況。5個哲學家去吃中餐,坐在 張圓桌旁。他們有5根筷子 而不是5雙 並且每兩個人中間放一根筷子。哲學家們時而思考,時而進餐。每個人都需要 雙筷子才能吃到東西,並在吃完後將筷子放回原處繼續思考。有些筷子管理演算法能夠使每個人都能相對及時地吃到東西 例...
第十章 避免活躍性危險
1.死鎖 檢測死鎖 在等待關係的有向圖中搜尋迴圈。產生死鎖的4個必要條件 1 互斥條件 共享資源獨佔訪問 2 不可剝奪條件 不能強制其他執行緒釋放資源 3 請求和保持條件 在等待申請的新的資源時,繼續占有已分配的資源 4 迴圈等待條件 發生死鎖時,存在乙個迴圈等待的佇列 p1等待p2占有的資源,p2...
多執行緒 7 執行緒安全性,活躍性,效能問題
安全性 資料競爭 多個執行緒同時訪問乙個資料,並且至少有乙個執行緒會寫這個資料。競態條件 程式的執行結果依賴程式執行的順序。也可以按照以下的方式理解競態條件 程式的執行依賴於某個狀態變數,在判斷滿足條件的時候執行,但是在執行時其他變數同時修改了狀態變數。if 狀態變數 滿足 執行條件 活躍性 死鎖 ...