同步鎖以及如何避免死鎖?

2021-09-19 08:55:17 字數 2594 閱讀 6867

同步:在高併發的情況下,為了防止資料出錯,乙個執行緒對於共享資源執行操作的時候,另外的執行緒要執行操作此共享資源需要等待前乙個執行緒釋放此共享資源,才能操作。

同步監視器:共享資源。

同步函式:synchronized修飾的方法,同步監視器為當前this物件。

同步**塊:synchronized修飾的**塊,同步監視器可以自定義。

同步鎖lock:另一種更加強大的執行緒安全機制:通過顯示的定義同步鎖物件來實現同步,同步鎖物件由lock物件充當。

兩者同步機制的區別:lock是顯示的使用lock物件作為同步監視器,同步方法隱式的使用當前物件作為同步監視器。

lock開啟後必須關閉:lock()//加鎖    unlock()//釋放鎖

死鎖:簡單來說就是兩個沒有釋放的同步程序都想取得對方共享資源(同步監視器)的操作權。

舉個例子:有同步函式a,b 有資源a1,b1 問題:a,b都想取得a1,b1的操作權。

假設:a先取的a1的操作權,同時b取得了b1的操作權,此時,a再想取得b1得操作權必須等同步函式b先釋放資源,但是b由於沒有拿到a1得操作權所以一直沒有釋放資源。此時就會造成執行緒得等待死鎖(阻塞死鎖)

死鎖分類:

1.等待死鎖(如上)。

2.遞迴死鎖:(一般很少人在遞迴函式裡面加鎖,很容易死翹翹)

舉例:a同步函式,b非同步函式。a同步函式裡呼叫了b非同步函式,但是b非同步程序裡又呼叫了a同步程序。

假設:執行a同步函式時,由於a中同步函式呼叫了b函式,所以進入b函式,b函式再次呼叫了a同步函式,因為之前得a同步函式資源還沒有釋放,再從b函式中呼叫a同步函式會造成,再次呼叫得a同步函式進入遞迴死鎖狀態。

避免死鎖得技術:

1.加鎖順序

所有執行緒按照一定順序獲取鎖,避免按照不同順序加鎖時出現死鎖。

舉例:

有執行緒a&b&c,有鎖:lock1&lock2&lock3ab

ca想獲得lock3,必須先獲得lock1,但是lock1被c加鎖。所以a需要等待c釋放即可,

a獲得lock1,繼續獲得lock2,想獲得lock2必須等待b釋放資源。等待b釋放資源,a終於獲得lock3。

反例:

有執行緒a&b&c,有鎖:lock1&lock2&lock3ab

ca想獲得lock3, b想獲得lock1,a獲得了lock1,開始獲得lock2,等待c釋放資源,

此時b獲得lock3,需要獲得lock1。c釋放資源後,a獲得lock2,但是此時lock3被b加鎖,但是lock1又被a加鎖。此時a,b就發生了死鎖。

缺點:需要知道所有加鎖情況,全域性分析(難以避免未知情況)

2.加鎖時限

在獲取鎖的過程中加上超時時間,超時則釋放資源並回退,稍後再嘗試加鎖。

舉例:

如1中的反例:假設a執行緒設定了300毫秒的限時,b執行緒設定了100毫秒的限時,

如果b等待時間超過限時,釋放資源並回退,此時a就可以成功獲得所有鎖並結束程式。然後b再嘗試獲取鎖,就可以解決死鎖問題。

缺點:當執行緒增至10條或20條以上,各執行緒的限時時長就越發接近,那麼越容易造成死鎖。例如:如果上例子中a,b執行緒限時時常一樣,那麼死鎖依然會發生。

3.死鎖檢測

死鎖檢測機制,主要針對順序加鎖和加鎖限時都無法實現的情況下使用。

原理:每當乙個執行緒獲得或者請求鎖後,獲得或請求的鎖資訊會在鎖和執行緒的資料結構中記錄下來。當乙個執行緒請求鎖失敗時,會遍歷鎖的關係圖,檢視是否發生死鎖。

舉例:

簡單例子:

有執行緒a,b, 有鎖lock1,lock2ab

此時當a請求lock2失敗時,會檢測自身是否加鎖了b請求的鎖。如果有就發生了死鎖。

複雜例子:

多執行緒的遞迴檢測死鎖:

有執行緒a,b,c,d 有鎖lock1,lock2,lock3,lock4ab

cda加鎖lock1,加鎖lock2時請求失敗,檢測鎖的關係圖,發現lock2被b加鎖,

b請求的lock3,又被c加鎖,c請求的lock4又被d加鎖,d請求的lock1又被

a加鎖。造成遞迴加鎖。

當檢測到死鎖後:執行緒回退,等待一段時間再重新嘗試加鎖。

死鎖以及避免死鎖

目錄 一 什麼是死鎖 二 產生死鎖的四個必要條件 三 避免死鎖的方法 是指兩個或兩個以上的程序在執行過程中,由於競爭資源或者由於彼此通訊而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。1.互斥 某種資源一次只允...

死鎖發生的條件以及如何避免死鎖

死鎖 死鎖,它是作業系統或軟體執行的一種狀態 在多工下,當乙個或多個程序等待系統資源而資源又被系統本身 或其它程序占用時,就形成了死鎖。死鎖發生的最常見形式是兩個或多個執行緒等待被另乙個執行緒占用的資源 如果兩個順序同時發生,執行緒1將永遠無法獲得鎖b,因為鎖b被執行緒2占有。同時執行緒2也永遠無法...

Linux 什麼是死鎖以及如何避免死鎖

介紹死鎖之前,先來說一下作業系統中的資源分類 按照使用次數分類 1 可重用性資源 每乙個可重用資源中的單元只能分配給乙個程序使用,不允許多個執行緒共享。程序使用資源順序 1 請求資源,如果請求失敗程序阻塞或迴圈等待 2 使用資源 3 釋放資源。系統中的可重用資源數目都是相對固定的程式執行時不能增加或...