天天看點

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 可以提高多個線程進行讀操作的效率,既就是實作讀寫鎖等。