公平鎖和非公平鎖

2021-10-14 06:48:30 字數 1617 閱讀 5566

三:reentrantlock非公平鎖

三:reentrantlock公平鎖

有個小夥伴最近諮詢我,前段時間他被面試官問了synchronized是公平鎖還是非公平鎖?當時就矇圈了,最後面試結果可想而知,今天我們就用乙個通俗的案例加上**來說明公平鎖和非公平鎖。其實公平鎖這個概念是juc工具包才有的,比如reentrantlock才有公平鎖的概念,這篇文章我們結合生活中的例項用2段**說明reentrantlock公平鎖和非公平鎖,以及證明synchronized是非公平鎖的。希望對小夥伴有幫助。

public

class

syncunfairlocktest}}

public

static

void

main

(string[

] args)

,"同學編號:00"

+(i+1)

).start()

;}}}

public

class

unfairlocktest

catch

(exception e)

finally}}

public

static

void

main

(string[

] args)

throws interruptedexception

,"同學編號:00"

+(i+1)

).start()

;}}}

基於上面的案例,我們不重複貼**了,將上述**中13行的private static final lock lock = new reentrantlock(false);引數由false改為true,private static final lock lock = new reentrantlock(true);無論執行多少次可以得出乙個結論:先排隊的童鞋能先打飯,不允許插對體現的就是公平鎖。

reentrantlock是基於abstractqueuedsynchronizer(抽象佇列同步器,簡稱aqs)實現的,aqs底層維護了乙個帶頭的雙向鍊錶,用來同步執行緒,鍊錶每個節點用node表示,每個node會記錄執行緒資訊,上下節點,節點狀態等資訊,aqs控制node的生命週期。如下圖所示,aqs也包含條件佇列,鎖和條件佇列(condition)是一對多的關係,也就是說乙個鎖可以對應多個條件佇列,執行緒間的通訊在條件佇列裡通過await,single/singleall方法控制,synchronized只有乙個條件佇列用wait,notify/notifyall來實現,這裡不展開說了,《母雞下蛋例項:多執行緒通訊生產者和消費者wait/notify和condition/await/signal條件佇列》和《synchronized用法原理和鎖優化公升級過程(面試)》可以看我文章,裡面有大量清晰簡單案例。條件佇列也是以鍊錶形式存在。lock是基於juc包實現,synchronized是本地方法基於c++實現。

公平鎖和非公平鎖

公平鎖和非公平鎖的不同是發生在乙個新的執行緒搶占乙個鎖的情況下。1.對於非公平鎖,當乙個新的執行緒想要得到乙個鎖,而這時鎖恰好沒有被別的執行緒占有,那麼這時候這個新的執行緒就可以無視其他執行緒在等待佇列中的排隊,而直接獲取這個鎖,而且不用先加入等待佇列。2,公平鎖,就是乙個新的執行緒想要得到乙個鎖,...

公平鎖和非公平鎖

所謂公平鎖指的是哪個執行緒先執行,那就可以先得到鎖。非公平鎖是不管執行緒是否是先執行,上來就直接嘗試占有鎖,如果嘗試失敗,就再採用類似公平鎖那種方式。我們看下reentrantlock 類的原始碼 公平鎖 protected final boolean tryacquire int acquires...

公平鎖與非公平鎖

在reentrantlock中很明顯可以看到其中同步包括兩種,分別是公平的fairsync和非公平的nonfairsync。公平鎖的作用就是嚴格按照執行緒啟動的順序來執行的,不允許其他執行緒插隊執行的 而非公平鎖是允許插隊的。預設情況下reentrantlock是通過非公平鎖來進行同步的,包括syn...