Lock 接口與 synchronized 關鍵字的區別

 

      

拷貝別的博主總結的9點不同:

1.JDK版本不同

synchronized關鍵字產生於JKD1.5之前,是低版本保證共享資源同步訪問的主要技術。
Lock接口產生於JDK1.5版本,位於著名的java.util.concurrent併發包中,是Java提供的一種比synchronized關鍵字更加靈活與豐富的共享資源同步訪問技術。


2.讀寫鎖

synchronized關鍵字只提供了一種鎖,即獨佔鎖。
Lock接口不僅提供了與前者類似的獨佔鎖,而且還通過ReadWriteLock接口提供了讀鎖和寫鎖。
讀寫鎖最大的優勢在於讀鎖與讀鎖並不獨佔,提高了共享資源的使用效率。


3.塊鎖與鏈鎖

synchronized關鍵字以代碼塊或者說是作用域機制實現了加鎖與解鎖,我簡稱爲塊鎖。synchronized關鍵字的作用域機制導致同步塊必須包含在同一方法中,且多個鎖的加鎖與解鎖順序正好相反,即:{{{}}}結構。
Lock接口並不限制鎖的作用域和加解鎖次序,可以提供類似於鏈表樣式的鎖,所以我簡稱爲鏈鎖。Lock接口並不需要把加鎖和解鎖方法放在同一方法中,且加鎖和解鎖順序完全隨意,即:{{}{}}結構。


4.解鎖方式

synchronized關鍵字:隨着同步塊/方法執行完畢,自動解鎖。
Lock接口:需要手動通過lock.unlock()方法解鎖,一般此操作位於finally{}中。


5.阻塞鎖與非阻塞鎖

synchronized關鍵字提供的鎖是阻塞的,它會一直嘗試通過輪詢去獲取對象的監視鎖。
Lock接口通過lock.tryLock()方法提供了一種非阻塞的鎖,它會嘗試去獲取鎖,如果沒有獲取鎖,則不再嘗試。


6.可中斷鎖

synchronized關鍵字提供的鎖是不可中斷的,它會一直嘗試去獲取鎖,我們無法手動的中斷它。
Lock接口通過lock.lockInterruptibly()提供了一種可中斷的鎖,我們可以主動的去中斷這個鎖,避免死鎖的發生。


7.可超時鎖

synchronized關鍵字提供的鎖是不可超時的,它會一直嘗試去獲取鎖,直至獲取鎖。
Lock接口通過{tryLock(long, TimeUnit)方法}方法提供了一種可超時的鎖,它會在一段時間內嘗試去獲取鎖,如果限定時間超時,則不再嘗試去獲取鎖,避免死鎖的發生。


8.公平鎖(線程次序保證)

我們都知道,如果高併發環境下多個線程嘗試去訪問同一共享資源,同一時刻只有一個線程擁有訪問這個共享資源的鎖,其他的線程都在等待。

synchronized關鍵字提供的鎖是非公平鎖,如果持有鎖的線程釋放了鎖,則新進入的線程與早就等待的線程擁有同樣的機會獲取這個鎖,簡單來說就是不講究:先來後到,反而講究:來得早不如來得巧。非公平鎖可能導致某些線程永遠都不會獲取鎖。
Lock接口默認也是非公平鎖,但是他還可以通過fair參數指定爲公平鎖。在公平鎖機制下,等待的線程都會被標記等待次數,等待次數越多的鎖獲取鎖的優先級越高,也就是常說的:先到先得。


9.互不干擾、可以共用

synchronized關鍵字是通過關鍵字實現對對象的加鎖與解鎖的。
Lock接口是通過Lock接口的實現類的實例對象的lock()和unlock()方法實現加鎖與解鎖的。
我們也可以通過synchronized關鍵字對Lock接口的實現類的實例對象進行監視器鎖的加鎖與解鎖。而且對監視器鎖的加鎖與解鎖與Lock接口的實現類的實例對象的lock()和unlock()方法並不衝突。
也就是說我們可以同時使用Lock接口和synchronized關鍵字實現同步訪問控制。
但是,原則上是極其不建議這種混搭的同步訪問控制方式的,不僅代碼難以閱讀,而且容易出錯。
 

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