執行緒鎖和死鎖
公平鎖和非公平鎖
==公平鎖:先等待的執行緒先獲得鎖,先到先得,不能插隊
==非公平鎖:能夠執行緒插隊的鎖,根據一定策略來進行排程,可能時間片少的先排程,可以進行插隊
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可以中斷