存在層次上 synchronized: Java的關鍵字,在jvm層面上 Lock: 是一個介面 鎖的釋放 synchronized: 1、以獲取鎖的線程執行完同步代碼,釋放鎖 2、線程執行發生異常,jvm會讓線程釋放鎖 Lock: 在finally中必須釋放鎖,不然容易造成線程死鎖 鎖的獲取 sy ...
存在層次上
synchronized: Java的關鍵字,在jvm層面上
Lock: 是一個介面
鎖的釋放
synchronized: 1、以獲取鎖的線程執行完同步代碼,釋放鎖 2、線程執行發生異常,jvm會讓線程釋放鎖
Lock: 在finally中必須釋放鎖,不然容易造成線程死鎖
鎖的獲取
synchronized: 假設A線程獲得鎖,B線程等待。如果A線程阻塞,B線程會一直等待
Lock: 分情況而定,Lock有多個鎖獲取的方式,大致就是可以嘗試獲得鎖,線程可以不用一直等待(可以通過tryLock判斷有沒有鎖)
鎖的釋放(死鎖產生)
synchronized: 在發生異常時候會自動釋放占有的鎖,因此不會出現死鎖
Lock: 發生異常時候,不會主動釋放占有的鎖,必須手動unlock來釋放鎖,可能引起死鎖的發生
鎖的狀態
synchronized: 無法判斷
Lock: 可以判斷
鎖的類型
synchronized: 可重入 不可中斷 非公平
Lock: 可重入 可判斷 可公平(兩者皆可)
性能
synchronized: 少量同步
Lock: 大量同步
- Lock可以提高多個線程進行讀操作的效率。(可以通過readwritelock實現讀寫分離)
- 在資源競爭不是很激烈的情況下,Synchronized的性能要優於ReetrantLock,但是在資源競爭很激烈的情況下,Synchronized的性能會下降幾十倍,但是ReetrantLock的性能能維持常態;
- ReentrantLock提供了多樣化的同步,比如有時間限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在資源競爭不激烈的情形下,性能稍微比synchronized差點點。但是當同步非常激烈的時候,synchronized的性能一下子能下降好幾十倍。而ReentrantLock確還能維持常態。
調度
synchronized: 使用Object對象本身的wait 、notify、notifyAll調度機制
Lock: 可以使用Condition進行線程之間的調度
用法
synchronized: 在需要同步的對象中加入此控制,synchronized可以加在方法上,也可以加在特定代碼塊中,括弧中表示需要鎖的對象。
Lock: 一般使用ReentrantLock類做為鎖。在加鎖和解鎖處需要通過lock()和unlock()顯示指出。所以一般會在finally塊中寫unlock()以防死鎖。
底層實現
synchronized: 底層使用指令碼方式來控制鎖的,映射成位元組碼指令就是增加來兩個指令:monitorenter和monitorexit。當線程執行遇到monitorenter指令時會嘗試獲取內置鎖,如果獲取鎖則鎖計數器+1,如果沒有獲取鎖則阻塞;當遇到monitorexit指令時鎖計數器-1,如果計數器為0則釋放鎖。
Lock: 底層是CAS樂觀鎖,依賴AbstractQueuedSynchronizer類,把所有的請求線程構成一個CLH隊列。而對該隊列的操作均通過Lock-Free(CAS)操作。
此博客只是為了記憶相關知識點,大部分為網路上的文章,在此向各個文章的作者表示感謝!