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