synchronized和ReentrantLock實現原理,以及兩者的區別

synchronized和ReentrantLock是如何實現的?以及它們有什麼區別?

1 .synchronized屬於獨佔式悲觀鎖,是通過JVM隱式實現的,synchronized只允許同一時刻只有一個線程操作資源.

在java中每個對象都隱式包含了一個monitor(監視器) 對象,加鎖的過程其實就是競爭monitor的過程,當線程進入字節碼monitorenter指令後,線程將持有monitor對象,執行monitorexit時釋放monitor對象,當其他線程沒有拿到monitor對象時,則需要阻塞等待獲取該對象.

2.ReentrantLock是Lock的默認實現方式之一,它是基於AQS(Abstract Queued Synchronizer,隊列同步器) 實現的,它默認是通過非公平鎖實現的,在它的內部都有一個state的狀態字段用於表示鎖被佔用的,如果是0 則標識鎖未被佔用,此時線程就可以把state改爲1,併成功獲取,而其他未獲得鎖的線程只能去排隊等待獲取鎖資源.

 

兩者的相同點:

1. 都是用來協調多線程對共享對象、變量的訪問
2. 都是可重入鎖,同一線程可以多次獲得同一個鎖
3. 都保證了可見性和互斥性
兩者的不同點:
 
1. ReentrantLock 顯示的獲得、釋放鎖,synchronized 隱式獲得釋放鎖
2. ReentrantLock 可響應中斷、可輪迴,synchronized 是不可以響應中斷的,爲處理鎖的
不可用性提供了更高的靈活性
3. ReentrantLock 是 API 級別的,synchronized 是 JVM 級別的
4. ReentrantLock 可以實現公平鎖
5. ReentrantLock 通過 Condition 可以綁定多個條件
6. 底層實現不一樣, synchronized 是同步阻塞,使用的是悲觀併發策略,lock 是同步非阻
塞,採用的是樂觀併發策略
7. Lock 是一個接口,而 synchronized 是 Java 中的關鍵字,synchronized 是內置的語言
實現。
8. synchronized 在發生異常時,會自動釋放線程佔有的鎖,因此不會導致死鎖現象發生;
而 Lock 在發生異常時,如果沒有主動通過 unLock()去釋放鎖,則很可能造成死鎖現象,
因此使用 Lock 時需要在 finally 塊中釋放鎖。
9. Lock 可以讓等待鎖的線程響應中斷,而 synchronized 卻不行,使用 synchronized 時,
等待的線程會一直等待下去,不能夠響應中斷。
10. 通過 Lock 可以知道有沒有成功獲取鎖,而 synchronized 卻無法辦到。
11. Lock 可以提高多個線程進行讀操作的效率,既就是實現讀寫鎖等。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章