摘要:同樣的線程,線程,線程也阻塞掛起加入隊(duì)列中。至此在時(shí)刻的隊(duì)列如圖時(shí)刻線程執(zhí)行完畢,調(diào)用方法釋放鎖并從隊(duì)列中取出哨兵節(jié)點(diǎn)的下一節(jié)點(diǎn),也就是此刻的線程,并喚醒該線程。線程再次嘗試獲取鎖,如果鎖獲取成功將繼續(xù)執(zhí)行線程代碼。
AQS 全稱(chēng):AbstractQueuedSynchronizer,它是JUC并發(fā)工具包中 ReentrantLock 、CountDownLatch、CyclicBarrier等這些類(lèi)的底層實(shí)現(xiàn)。此篇我們主要通過(guò)ReentrantLock的使用來(lái)大體了解AQS底層代碼設(shè)計(jì)原理,不對(duì)源碼詳細(xì)贅述。只要對(duì)整體的設(shè)計(jì)方向有清晰了解,再去追蹤源碼便不是什么難事。閱讀本篇之前,需要大家對(duì)ReentrantLock 的API有一定了解。
ReentrantLock的lock、await方法底層邏輯在使用ReentrantLock進(jìn)行代碼塊同步,一般都會(huì)有如下寫(xiě)法:
ReentrantLock lock = new ReentrantLock(true); Condition condition = lock.newCondition(); try{ lock.lock(); //..... condition.await(); }finally{ lock.unlock(); }
假設(shè) T1 時(shí)刻有10個(gè)線程調(diào)用同一個(gè)ReentrantLock實(shí)例的lock()方法, 線程1 先獲取鎖成功,緊接著線程2 調(diào)用lock()方法,發(fā)現(xiàn)獲取鎖失?。ㄍㄟ^(guò)CAS操作對(duì)狀態(tài)位進(jìn)行標(biāo)記),則線程2被封裝成Node節(jié)點(diǎn)放入AQS雙向隊(duì)列中,并調(diào)用LockSupport.park()阻塞掛起。同樣的線程3,線程4,...線程10 也阻塞掛起加入隊(duì)列中。至此在t1時(shí)刻 AQS的隊(duì)列如圖1-1:
T4 時(shí)刻線程1執(zhí)行完畢,調(diào)用unlock()方法釋放鎖并從AQS隊(duì)列中取出哨兵節(jié)點(diǎn)的下一節(jié)點(diǎn),也就是此刻的線程2,并喚醒該線程。線程2再次嘗試獲取鎖,如果鎖獲取成功將繼續(xù)執(zhí)行線程2代碼。如果失敗會(huì)被再次封裝成Node節(jié)點(diǎn)放入AQS隊(duì)列中去??吹竭@里大家可能會(huì)有疑問(wèn):為什么線程1的鎖釋放完后喚醒的是線程2,而不是線程3 或者線程 4 呢?這里是因?yàn)楣芥i與非公平鎖的原因,如果采用了公平鎖那么將按照先進(jìn)先出的原則讓線程去搶占鎖,而非公平鎖沒(méi)有先后順序的限制。對(duì)于ReentrantLock可以通過(guò)構(gòu)造函數(shù)的參數(shù)進(jìn)行指定,默認(rèn)它采用的是非公平鎖。
Lock 與 Condition結(jié)合使用又是什么樣的原理呢?我們緊接著上面的分析,線程T1時(shí)刻獲取鎖成功后,在T2時(shí)刻調(diào)用了condition.await()方法時(shí)會(huì)發(fā)生以下4件事情:
釋放鎖(通過(guò)CAS操作對(duì)狀態(tài)為進(jìn)行標(biāo)記)
阻塞掛起線程1
線程1封裝成Node節(jié)點(diǎn)放入條件隊(duì)列中(注意:此處條件隊(duì)列和AQS隊(duì)列不是一回事)
喚醒AQS隊(duì)列中阻塞掛起的線程
當(dāng)其他線程調(diào)用condition.signal() 或者 condition.sigalAll() 方法時(shí),會(huì)將條件隊(duì)列的一個(gè)或者全部Node節(jié)點(diǎn)移到AQS隊(duì)列中。
一個(gè)鎖對(duì)應(yīng)一個(gè)AQS隊(duì)列、多個(gè)condition、多個(gè)條件隊(duì)列,條件隊(duì)列的個(gè)數(shù)是跟隨Condition走的。我們通過(guò)1-2圖來(lái)更直觀認(rèn)識(shí) Lock、Condition、AQS隊(duì)列、條件隊(duì)列之間的關(guān)系。
至此ReentrantLock底層使用AQS來(lái)實(shí)現(xiàn)線程同步的設(shè)計(jì)已講解完畢,趕緊擼源碼去吧?。?!
書(shū)寫(xiě)技術(shù)文章是一個(gè)循序漸進(jìn)的過(guò)程,所以我不能保證每句話、每行代碼都是對(duì)的,但至少能保證不復(fù)制、不粘貼,每篇文章都是自己對(duì)技術(shù)的認(rèn)識(shí)、細(xì)心斟酌總結(jié)出來(lái)的。喬布斯說(shuō):我們?cè)谶@個(gè)星球上的時(shí)間都很短,很少有機(jī)會(huì)去做幾件真正偉大的事情,同時(shí)要做得好,我必須要趁我還年輕的時(shí)候完成這些事。
其實(shí)我想說(shuō)的是,我是一枚程序員,我只想在有限的時(shí)間內(nèi)盡可能去沉淀我這一生中所能沉淀下來(lái)的東西。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/74439.html
摘要:表示的是兩個(gè),當(dāng)其中任意一個(gè)計(jì)算完并發(fā)編程之是線程安全并且高效的,在并發(fā)編程中經(jīng)常可見(jiàn)它的使用,在開(kāi)始分析它的高并發(fā)實(shí)現(xiàn)機(jī)制前,先講講廢話,看看它是如何被引入的。電商秒殺和搶購(gòu),是兩個(gè)比較典型的互聯(lián)網(wǎng)高并發(fā)場(chǎng)景。 干貨:深度剖析分布式搜索引擎設(shè)計(jì) 分布式,高可用,和機(jī)器學(xué)習(xí)一樣,最近幾年被提及得最多的名詞,聽(tīng)名字多牛逼,來(lái),我們一步一步來(lái)?yè)羝魄皟蓚€(gè)名詞,今天我們首先來(lái)說(shuō)說(shuō)分布式。 探究...
摘要:表示的是兩個(gè),當(dāng)其中任意一個(gè)計(jì)算完并發(fā)編程之是線程安全并且高效的,在并發(fā)編程中經(jīng)??梢?jiàn)它的使用,在開(kāi)始分析它的高并發(fā)實(shí)現(xiàn)機(jī)制前,先講講廢話,看看它是如何被引入的。電商秒殺和搶購(gòu),是兩個(gè)比較典型的互聯(lián)網(wǎng)高并發(fā)場(chǎng)景。 干貨:深度剖析分布式搜索引擎設(shè)計(jì) 分布式,高可用,和機(jī)器學(xué)習(xí)一樣,最近幾年被提及得最多的名詞,聽(tīng)名字多牛逼,來(lái),我們一步一步來(lái)?yè)羝魄皟蓚€(gè)名詞,今天我們首先來(lái)說(shuō)說(shuō)分布式。 探究...
摘要:表示的是兩個(gè),當(dāng)其中任意一個(gè)計(jì)算完并發(fā)編程之是線程安全并且高效的,在并發(fā)編程中經(jīng)??梢?jiàn)它的使用,在開(kāi)始分析它的高并發(fā)實(shí)現(xiàn)機(jī)制前,先講講廢話,看看它是如何被引入的。電商秒殺和搶購(gòu),是兩個(gè)比較典型的互聯(lián)網(wǎng)高并發(fā)場(chǎng)景。 干貨:深度剖析分布式搜索引擎設(shè)計(jì) 分布式,高可用,和機(jī)器學(xué)習(xí)一樣,最近幾年被提及得最多的名詞,聽(tīng)名字多牛逼,來(lái),我們一步一步來(lái)?yè)羝魄皟蓚€(gè)名詞,今天我們首先來(lái)說(shuō)說(shuō)分布式。 探究...
摘要:我在面試題中也見(jiàn)過(guò)他的身影,但一直不知道是什么東西。直到當(dāng)前線程被或者獲取到資源,結(jié)束。簡(jiǎn)簡(jiǎn)單單把過(guò)一遍明天就看顯式鎖實(shí)現(xiàn)咯參考資料如果文章有錯(cuò)的地方歡迎指正,大家互相交流。為了大家方便,剛新建了一下群,大家也可以去交流交流。 前言 回顧前面: 多線程三分鐘就可以入個(gè)門(mén)了! Thread源碼剖析 多線程基礎(chǔ)必要知識(shí)點(diǎn)!看了學(xué)習(xí)多線程事半功倍 Java鎖機(jī)制了解一下 只有光頭才能變強(qiáng)...
閱讀 1398·2021-09-04 16:40
閱讀 3514·2021-07-28 00:13
閱讀 2949·2019-08-30 11:19
閱讀 2671·2019-08-29 12:29
閱讀 3222·2019-08-29 12:24
閱讀 1170·2019-08-26 13:28
閱讀 2458·2019-08-26 12:01
閱讀 3503·2019-08-26 11:35