Java多線程——公平鎖和非公平鎖

在java的鎖機制中,公平和非公平的參考物是什么乍赫,個人而言覺得是相對產(chǎn)生的結果而立瓣蛀,簡單的來說,如果一個線程組里耿焊,能保證每個線程都能拿到鎖揪惦,那么這個鎖就是公平鎖。相反罗侯,如果保證不了每個線程都能拿到鎖器腋,也就是存在有線程餓死,那么這個鎖就是非公平鎖。本文圍繞ReenTrantLock來講纫塌。

小編推薦一個學JAVA的學習裙【四九二诊县,一七三,八四二】措左,無論你是牛還是小白依痊,是想轉行還是想入行都可以來了解一起進步一起學習!裙內有開發(fā)具怎披,很多干貨和技術資料分享實現(xiàn)原理

那如何能保證每個線程都能拿到鎖呢胸嘁,隊列FIFO是一個完美的解決方案,也就是先進先出凉逛,java的ReenTrantLock也就是用隊列實現(xiàn)的公平鎖和非公平鎖性宏。

在公平的鎖中,如果有另一個線程持有鎖或者有其他線程在等待隊列中等待這個所状飞,那么新發(fā)出的請求的線程將被放入到隊列中毫胜。而非公平鎖上,只有當鎖被某個線程持有時诬辈,新發(fā)出請求的線程才會被放入隊列中(此時和公平鎖是一樣的)酵使。所以,它們的差別在于非公平鎖會有更多的機會去搶占鎖焙糟。

公平鎖:

final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } #hasQueuedPredecessors的實現(xiàn) public final boolean hasQueuedPredecessors() { Node t = tail; // Read fields in reverse initialization order Node h = head; Node s; return h != t && ((s = h.next) == null || s.thread != Thread.currentThread()); }

非公平鎖:

final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } }

示例

小編推薦一個學JAVA的學習裙【四九二口渔,一七三,八四二】酬荞,無論你是牛還是小白搓劫,是想轉行還是想入行都可以來了解一起進步一起學習!裙內有開發(fā)具混巧,很多干貨和技術資料分享

公平鎖:

/** * Created by Fant.J. */public class MyFairLock { /** * true 表示 ReentrantLock 的公平鎖 */ private ReentrantLock lock = new ReentrantLock(true); public void testFail(){ try { lock.lock(); System.out.println(Thread.currentThread().getName() +"獲得了鎖"); }finally { lock.unlock(); } } public static void main(String[] args) { MyFairLock fairLock = new MyFairLock(); Runnable runnable = () -> { System.out.println(Thread.currentThread().getName()+"啟動"); nonfairLock.testFail(); }; Thread[] threadArray = new Thread[10]; for (int i=0; i<10; i++) { threadArray[i] = new Thread(runnable); } for (int i=0; i<10; i++) { threadArray[i].start(); } }}Thread-0啟動Thread-0獲得了鎖Thread-1啟動Thread-1獲得了鎖Thread-2啟動Thread-2獲得了鎖Thread-3啟動Thread-3獲得了鎖Thread-4啟動Thread-4獲得了鎖Thread-5啟動Thread-5獲得了鎖Thread-6啟動Thread-6獲得了鎖Thread-8啟動Thread-8獲得了鎖Thread-7啟動Thread-7獲得了鎖Thread-9啟動Thread-9獲得了鎖

可以看到枪向,獲取鎖的線程順序正是線程啟動的順序。

非公平鎖:

/** * Created by Fant.J. */public class MyNonfairLock { /** * false 表示 ReentrantLock 的非公平鎖 */ private ReentrantLock lock = new ReentrantLock(false); public void testFail(){ try { lock.lock(); System.out.println(Thread.currentThread().getName() +"獲得了鎖"); }finally { lock.unlock(); } } public static void main(String[] args) { MyNonfairLock nonfairLock = new MyNonfairLock(); Runnable runnable = () -> { System.out.println(Thread.currentThread().getName()+"啟動"); nonfairLock.testFail(); }; Thread[] threadArray = new Thread[10]; for (int i=0; i<10; i++) { threadArray[i] = new Thread(runnable); } for (int i=0; i<10; i++) { threadArray[i].start(); } }}Thread-1啟動Thread-0啟動Thread-0獲得了鎖Thread-1獲得了鎖Thread-8啟動Thread-8獲得了鎖Thread-3啟動Thread-3獲得了鎖Thread-4啟動Thread-4獲得了鎖Thread-5啟動Thread-2啟動Thread-9啟動Thread-5獲得了鎖Thread-2獲得了鎖Thread-9獲得了鎖Thread-6啟動Thread-7啟動Thread-6獲得了鎖Thread-7獲得了鎖

可以看出非公平鎖對鎖的獲取是亂序的咧党,即有一個搶占鎖的過程秘蛔。

最后

那非公平鎖和公平鎖適合什么場合使用呢,他們的優(yōu)缺點又是什么呢傍衡?

小編推薦一個學JAVA的學習裙【四九二深员,一七三,八四二】蛙埂,無論你是牛還是小白倦畅,是想轉行還是想入行都可以來了解一起進步一起學習!裙內有開發(fā)具绣的,很多干貨和技術資料分享

優(yōu)缺點:

非公平鎖性能高于公平鎖性能叠赐。首先欲账,在恢復一個被掛起的線程與該線程真正運行之間存在著嚴重的延遲。而且芭概,非公平鎖能更充分的利用cpu的時間片赛不,盡量的減少cpu空閑的狀態(tài)時間。

使用場景

使用場景的話呢罢洲,其實還是和他們的屬性一一相關踢故,舉個栗子:如果業(yè)務中線程占用(處理)時間要遠長于線程等待,那用非公平鎖其實效率并不明顯惹苗,但是用公平鎖會給業(yè)務增強很多的可控制性殿较。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鸽粉,隨后出現(xiàn)的幾起案子斜脂,更是在濱河造成了極大的恐慌,老刑警劉巖触机,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異玷或,居然都是意外死亡儡首,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門偏友,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔬胯,“玉大人,你說我怎么就攤上這事位他》毡簦” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵鹅髓,是天一觀的道長舞竿。 經(jīng)常有香客問我,道長窿冯,這世上最難降的妖魔是什么骗奖? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮醒串,結果婚禮上执桌,老公的妹妹穿的比我還像新娘。我一直安慰自己芜赌,他們只是感情好仰挣,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缠沈,像睡著了一般膘壶。 火紅的嫁衣襯著肌膚如雪违柏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天香椎,我揣著相機與錄音漱竖,去河邊找鬼。 笑死畜伐,一個胖子當著我的面吹牛馍惹,可吹牛的內容都是我干的。 我是一名探鬼主播玛界,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼万矾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了慎框?” 一聲冷哼從身側響起良狈,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎笨枯,沒想到半個月后薪丁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡馅精,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年严嗜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洲敢。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡漫玄,死狀恐怖,靈堂內的尸體忽然破棺而出压彭,到底是詐尸還是另有隱情睦优,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布壮不,位于F島的核電站汗盘,受9級特大地震影響,放射性物質發(fā)生泄漏忆畅。R本人自食惡果不足惜衡未,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望家凯。 院中可真熱鬧缓醋,春花似錦、人聲如沸绊诲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掂之。三九已至抗俄,卻和暖如春脆丁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背动雹。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工槽卫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人胰蝠。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓歼培,卻偏偏與公主長得像,于是被迫代替她去往敵國和親茸塞。 傳聞我的和親對象是個殘疾皇子躲庄,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內容