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