synchronized與Lock

1、synchronized 是Java內(nèi)置的關(guān)鍵字,使用后會自動釋放鎖,

Lock是java.util.concurrent.Locks 包下的一個接口,必須要手動釋放。特別是在發(fā)生異常時,需要在 finally 塊中進(jìn)行手動釋放,否則會發(fā)生死鎖行為

synchronized 代碼清單

Lock 代碼清單

2、Lock可響應(yīng)中斷,而synchronized 不能響應(yīng)中斷,并且Lock提供了更豐富的方法實現(xiàn);例如

Lock() ; //獲取鎖

tryLock(); //獲取鎖

tryLock(long time, TimeUnit unit); //在一定時間單位內(nèi)等待

lockInterruptibly(); //獲取鎖,可響應(yīng)中斷(AB線程同時獲取鎖,A得到后,B進(jìn)行等待,則B會被Tread.interrupt()方法中端并可去執(zhí)行其他的代碼邏輯,而synchronized無法被中端)

unlock(); //釋放鎖

***以下對lockInterruptibly 進(jìn)行簡單的驗證,代碼結(jié)構(gòu)糙,只為驗證***



3、synchronized 是非公平鎖,即不能保證等待鎖線程的順序,

Lock的實現(xiàn) ReentrantLock 可通過實例化true or false 的構(gòu)造參數(shù)實現(xiàn)公平鎖和非公平鎖,默認(rèn)為非公平鎖

ReentrantLock的構(gòu)造參數(shù)

4、ReentrantLock是唯一實現(xiàn)了Lock接口的類,并且ReentrantLock提供了更多的方法

lck.isFair();

lck.isLocked();

lck.getHoldCount();

lck.getQueueLength();

lck.wait();

...

5、synchronized無法判斷是否獲取鎖的狀態(tài),Lock可以判斷是否獲取到鎖;

6、Lock鎖適合大量同步的代碼的同步問題,synchronized鎖適合代碼少量的同步問題。

7、都是可重入鎖:在執(zhí)行對象中所有同步方法不用再次獲得鎖

8、synchronized是一個悲觀鎖,Lock是一個樂觀鎖(底層基于volatile和cas實現(xiàn)),

二、底層實現(xiàn)

1、synchronznized映射成字節(jié)碼指令就是增加兩個指令:monitorenter、monitorexit,

當(dāng)一條線程執(zhí)行時遇到monitorenter指令時,它會嘗試去獲得鎖,如果獲得鎖,那么所計數(shù)器+1(為什么要加1,因為它是可重入鎖,可根據(jù)這個瑣計數(shù)器判斷鎖狀態(tài)),如果沒有獲得鎖,那么阻塞,

當(dāng)它遇到一個monitoerexit時,瑣計數(shù)器會-1,當(dāng)計數(shù)器為0時,就釋放鎖

(tips:節(jié)碼中出現(xiàn)的兩個monitoerexit指令的原因是:一個正常執(zhí)行-1,令一個異常時執(zhí)行,這兩個用goto的方式只執(zhí)行一個)

2、Lock底層則基于volatile和cas實現(xiàn)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容