Synchronized與Lock區別

Java裏面的兩種管程模型

之前我們瞭解了Java裏面的一種管程模型monitor,synchronized就是基於Monitor實現的管程模型,在這個模型裏面,synchronized中用鎖解決了資源互斥問題,然後提供了wait(),notify(),notifyAll() 一組方法解決了線程同步問題,Java裏面另一種管程模型就是Lock+Condition, 在此模型中 Lock是用來解決資源互斥的問題,而Condition裏也提供wait(),signal(),signalAll() 同樣也是解決線程同步問題,如果你理解了synchronized那麼我相信你再來看Lock+Condition也會很簡單。

 

我們用兩種管程模型一對比會發現,他們的邏輯基本沒什麼區別,同樣都是所用鎖解決互斥問題,提供了一個阻塞隊列,並同時提供了一組方法來對阻塞隊列的線程進行操作,達到解決線程同步的效果。也許你會想既然有了synchronized爲什麼jdk還要提供Lock和Condition呢,而且synchronized傻瓜式的應用更方便簡單,而Lock和Condition卻麻煩多了,要自己加鎖、釋放鎖,一不小心就出BUG了。

 

Synchronized和Lock的區別

當然,既然存在就有其合理性,也許你會想到Lock的性能要比synchronized好,在JDK1.6版本之前Lock的性能的確要比synchronized要好,但是在JDK1.6值周 synchronized做了一系列的優化後,synchronized的整體性能提升上來了,所以性能並非Lock存在的原因,那麼究竟是什麼原因讓JDK非得重複造輪子,答案就是Lock提供了更多解決死鎖問題的方法:

 

1、Lock提供了超時機制

超時機制可以讓我們更靈活的控制程序,而不必陷入等待鎖的死循環中,在一定時間內獲取不到鎖,線程就釋放出來繼續幹下面的事情,而synchronized一旦嘗試加鎖,就會死等,所以這種情況就有可能會出現死鎖。

 

2、Lock阻塞的線程可以響應中斷

synchronized線程一旦獲取鎖失敗就會進行阻塞,而阻塞狀態下的線程是無法響應中斷(Interrupted)的,而Lock是支持中斷響應的,一旦發現可能出現死鎖,可立即中斷某個線程。

 

3、Lock支持非阻塞的獲取鎖

Lock支持不阻塞的方式獲取鎖,以這種方式獲取鎖時會返回獲取鎖是否成功,當嘗試獲取鎖不成功時,線程並不會阻塞。

 

4、Lock+Condition可以支持多個條件

synchronized只有一個等待隊列,任何情況的阻塞都是放在一個隊列裏面的,Lock可以創建多個Condition隊列,不同的Condition控制不同的條件,每個Condition有單獨的一個隊列。

來源:知乎

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