-
1 # 老七玉
-
2 # 衛華科技
所謂死鎖:是指兩個或兩個以上的程序在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。由於資源佔用是互斥的,當某個程序提出申請資源後,使得有關程序在無外力協助下,永遠分配不到必需的資源而無法繼續執行,這就產生了一種特殊現象死鎖。
雖然程序在執行過程中,可能發生死鎖,但死鎖的發生也必須具備一定的條件,死鎖的發生必須具備以下四個必要條件。
1)互斥條件:指程序對所分配到的資源進行排它性使用,即在一段時間內某資源只由一個程序佔用。如果此時還有其它程序請求資源,則請求者只能等待,直至佔有資源的程序用畢釋放。
2)請求和保持條件:指程序已經保持至少一個資源,但又提出了新的資源請求,而該資源已被其它程序佔有,此時請求程序阻塞,但又對自己已獲得的其它資源保持不放。
3)不剝奪條件:指程序已獲得的資源,在未使用完之前,不能被剝奪,只能在使用完時由自己釋放。
4)環路等待條件:指在發生死鎖時,必然存在一個程序——資源的環形鏈,即程序集合{P0,P1,P2,···,Pn}中的P0正在等待一個P1佔用的資源;P1正在等待P2佔用的資源,……,Pn正在等待已被P0佔用的資源。
在系統中已經出現死鎖後,應該及時檢測到死鎖的發生,並採取適當的措施來解除死鎖。目前處理死鎖的方法可歸結為以下四種:
1) 預防死鎖
這是一種較簡單和直觀的事先預防的方法。方法是透過設定某些限制條件,去破壞產生死鎖的四個必要條件中的一個或者幾個,來預防發生死鎖。預防死鎖是一種較易實現的方法,已被廣泛使用。但是由於所施加的限制條件往往太嚴格,可能會導致系統資源利用率和系統吞吐量降低。
2) 避免死鎖
該方法同樣是屬於事先預防的策略,但它並不須事先採取各種限制措施去破壞產生死鎖的的四個必要條件,而是在資源的動態分配過程中,用某種方法去防止系統進入不安全狀態,從而避免發生死鎖。
3)檢測死鎖
這種方法並不須事先採取任何限制性措施,也不必檢查系統是否已經進入不安全區,此方法允許系統在執行過程中發生死鎖。但可透過系統所設定的檢測機構,及時地檢測出死鎖的發生,並精確地確定與死鎖有關的程序和資源,然後採取適當措施,從系統中將已發生的死鎖清除掉。
4)解除死鎖
這是與檢測死鎖相配套的一種措施。當檢測到系統中已發生死鎖時,須將程序從死鎖狀態中解脫出來。常用的實施方法是撤銷或掛起一些程序,以便回收一些資源,再將這些資源分配給已處於阻塞狀態的程序,使之轉為就緒狀態,以繼續執行。死鎖的檢測和解除措施,有可能使系統獲得較好的資源利用率和吞吐量,但在實現上難度也最大。
悲觀鎖:假定會發生併發衝突,遮蔽一切可能違反資料完整性的操作。
樂觀鎖:假設不會發生併發衝突,只在提交操作時檢查是否違反資料完整性。 樂觀鎖不能解決髒讀的問題
悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。
樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,可以使用版本號等機制。樂觀鎖適用於多讀的應用型別,這樣可以提高吞吐量,像資料庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。
-
3 # 小光童鞋
hreadLocal為每個執行緒維護一個本地變數。採用空間換時間,它用於執行緒間的資料隔離,為每一個使用該變數的執行緒提供一個副本,每 個執行緒都可以獨立地改變自己的副本,而不會和其他執行緒的副本衝突。ThreadLocal類中維護一個Map,用於儲存每一個執行緒的變數副本,Map中元素的鍵為執行緒對 象,而值為對應執行緒的變數副本。
回覆列表
死鎖是指兩個或兩個以上的程序在執行過程中,由於競爭資源或者由於彼此通訊而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。(百科定義)
綜上所述,產生死鎖4個必要條件:互斥、佔有且等待、不可搶佔、迴圈等待。
互斥:某種資源一次只允許一個程序訪問,即該資源一旦分配給某個程序,其他程序就不能再訪問,直到該程序訪問結束。
佔有且等待:一個程序本身佔有資源(一種或多種),同時還有資源未得到滿足,正在等待其他程序釋放該資源。
不可搶佔:別人已經佔有了某項資源,你不能因為自己也需要該資源,就去把別人的資源搶過來。
迴圈等待:存在一個程序鏈,使得每個程序都佔有下一個程序所需的至少一種資源。
當以上四個條件均滿足,必然會造成死鎖,發生死鎖的程序無法進行下去,它們所持有的資源也無法釋放。這樣會導致CPU的吞吐量下降。所以死鎖情況是會浪費系統資源和影響計算機的使用效能的。那麼,解決死鎖問題就是相當有必要的了。
透過連續多次檢視程序的函式呼叫關係堆疊, 死鎖執行緒將一直處於等鎖的狀態,對比多次的函式呼叫堆疊輸出結果,確定哪兩個執行緒(或者幾個執行緒)一直沒有變化且一直處於等鎖的狀態。
也可以透過JDK自帶的命令列工具Jstack來進行執行緒Dump分析。透過Jps來檢視java程序id,然後透過Jstack輸出執行緒dump資訊到檔案,根據dump資訊檔案進行分析,透過檢視檔案中的
DeadThread.run
資訊,找到具體執行緒的死鎖位置。