1. 程式人生 > 其它 >執行緒鎖和死鎖

執行緒鎖和死鎖

公平鎖和非公平鎖

==公平鎖:先等待的執行緒先獲得鎖,先到先得,不能插隊

==非公平鎖:能夠執行緒插隊的鎖,根據一定策略來進行排程,可能時間片少的先排程,可以進行插隊

1、執行緒死鎖

(1)多個執行緒各自佔有一些資源,並互相等待其它執行緒佔用的資源,導致多個執行緒都在等待物件釋放資源,同時進入阻塞狀態

(2)產生死鎖的四個必要條件

==互斥條件:一個資源每次只能被一個程序使用

==請求與保持條件:一個程序因請求資源而阻塞時,對已獲得的資源保持不放

==不剝奪條件:程序已獲得的資源,在未使用完之前,不能強行進行剝奪

==迴圈等待條件:若干程序間形成一種頭尾相接的迴圈等待資源的關係

(3)如果預防和避免執行緒死鎖

==1、破壞請求與保持條件:一次性申請所有的資源

==2、破壞不剝奪條件:佔用部分資源的執行緒進一步申請其它資源時,如果申請不到,可以主動釋放它佔用的資源

==3、破壞迴圈等待條件:靠按序申請資源來預防。按某一順序申請資源,釋放資源則反序釋放。破壞迴圈等待條件。

 

2、鎖Lock

(1)執行緒同步機制——通過顯示定義同步鎖物件實現同步。同步鎖:Lock物件

(2)java.util.concurrent.locks.Lock介面:控制多個執行緒對共享資源進行訪問

(3)鎖提供了對共享資源的獨佔訪問,每次只能有一個執行緒對Lock物件加鎖,執行緒開始訪問資源前應先獲得Lock物件。

(4)ReentrantLock(可重入鎖),擁有與synchronized相同的併發性和記憶體語義。在實現執行緒安全的控制中,比較常用,可以顯式加鎖、釋放鎖。

==ReentrantLock與synchronized的對比

=====都是可重入鎖

=====synchronized依賴於JVM實現,非公平鎖

=====ReentrantLock依賴於JDK層實現的(API)

lock.lock()加鎖,lock.unlock()解鎖(需要try\finally語句塊配合實現)

=====ReentrantLock比synchronized增加了一些高階功能

    1、等待可中斷 lock.lockInterruptibly():可以選擇煩請等待去處理其它事情

    2、可以指定公平鎖和非公平鎖,ReentrantLock預設是非公平鎖

          ReentrantLock(boolean fair)構造方法來選擇是否公平

    3、ReentrantLock類執行緒物件可以註冊在指定的Condition中,進行有選擇性的執行緒通知。

=====優先使用synchronized,除非要使用ReentrantLock高階功能。

(5)Lock與synchronized的對比

=====Lock是顯式鎖(需要手動加鎖,解鎖),synchronized是隱式鎖,出了作用域就會自動釋放

=====Lock只有程式碼塊鎖,synchronized有程式碼塊鎖(同步程式碼塊)和方法鎖(同步方法)

=====Lock鎖的使用,JVM將花費較少的時間來排程執行緒,效能更好,並且有更好的擴充套件性(提供更多的子類)

=====優先使用順序:Lock->同步程式碼塊->同步方法

=====synchronized不能判斷獲取鎖的狀態,lock可以判斷鎖的狀態

=====synchronized不可以中斷,lock可以中斷

=====synchronized適合鎖少量的程式碼同步問題 ,lock適合鎖大量的程式碼同步問題