1. 程式人生 > >“J.U.C”:CLH佇列鎖 (r)

“J.U.C”:CLH佇列鎖 (r)

在前面介紹的幾篇部落格中總是提到CLH佇列,在AQS中CLH佇列是維護一組執行緒的嚴格按照FIFO的佇列。他能夠確保無飢餓,嚴格的先來先服務的公平性。下圖是CLH佇列節點的示意圖:

2015112100001

在CLH佇列的節點QNode中包含有一個locked的欄位,該欄位表示該節點是否需要獲取鎖,為true表示需要獲取,為false表示不需要獲取。在CLH佇列中,節點與節點之間並不是通過next指標來連線的而是通過myPred所指向節點的變化情況來影響的myNode的行為。

假設有兩個執行緒(執行緒A、執行緒B)。開始執行緒A需要獲得鎖,那麼他會建立一個QNode節點,並將locked設定為true(表示需要獲取鎖),同時獲取一個指向前驅的myPred並在前驅節點的的locked上面旋轉直到前驅節點是否鎖為止(locked為false,這個動作我們一般稱之為自旋),當然這裡會將tail指向自身來表示它是CLH佇列的最後一個節點,如下:

2015112500002

然後執行緒B新增到CLH佇列中,這時tail域應該指向執行緒B。

2015112500001

CLH佇列鎖的優點在於空間複雜度低(如果有n個執行緒,L個鎖,每個執行緒每次只獲取一個鎖,那麼需要的儲存空間是O(L+n),n個執行緒有n個myNode,L個鎖有L個tail)。CLH的變種體被運用到了AQS中。

參考文獻

相關推薦

J.U.CCLH佇列 (r)

在前面介紹的幾篇部落格中總是提到CLH佇列,在AQS中CLH佇列是維護一組執行緒的嚴格按照FIFO的佇列。他能夠確保無飢餓,嚴格的先來先服務的公平性。下圖是CLH佇列節點的示意圖: 在CLH佇列的節點QNode中包含有一個locked的欄位,該欄位表示該節點是否需要

J.U.C 之阻塞佇列ArrayBlockingQueue

1. 簡介 ArrayBlockingQueue,一個由陣列實現的有界阻塞佇列。該佇列採用 FIFO 的原則對元素進行排序新增的。 ArrayBlockingQueue 為有界且固定,其大小在構造時由建構函式來決定,確認之後就不能再改變了。 ArrayBlockin

【死磕Java併發】-----J.U.C之阻塞佇列ArrayBlockingQueue

ArrayBlockingQueue,一個由陣列實現的有界阻塞佇列。該佇列採用FIFO的原則對元素進行排序新增的。 ArrayBlockingQueue為有界且固定,其大小在構造時由建構函式來決定,確認之後就不能再改變了。ArrayBlockingQueu

J.U.C之重入ReentrantLock

此篇部落格所有原始碼均來自JDK 1.8 ReentrantLock,可重入鎖,是一種遞迴無阻塞的同步機制。它可以等同於synchronized的使用,但是ReentrantLock提供了比synchronized更強大、靈活的鎖機制,可以減少死鎖發生的概率。 API介

【死磕Java併發】-----J.U.C之重入ReentrantLock

此篇部落格所有原始碼均來自JDK 1.8 ReentrantLock,可重入鎖,是一種遞迴無阻塞的同步機制。它可以等同於synchronized的使用,但是ReentrantLock提供了比synchronized更強大、靈活的鎖機制,可以減少死鎖發生

【死磕Java併發】-----J.U.C之阻塞佇列DelayQueue

DelayQueue是一個支援延時獲取元素的無界阻塞佇列。裡面的元素全部都是“可延期”的元素,列頭的元素是最先“到期”的元素,如果佇列裡面沒有元素到期,是不能從列頭獲取元素的,哪怕有元素也不行。也就是說只有在延遲期到時才能夠從佇列中取元素。 DelayQu

死磕Java併發J.U.C之阻塞佇列DelayQueue

作者:chenssy  公眾號:Java技術驛站DelayQueue是一個支援延時獲取元素的無界

【Java並發編程實戰】—–“J.U.CReentrantLock之二lock方法分析

b2c check 條件 維護 box 抽象 post eight 若是 前一篇博客簡介了ReentrantLock的定義和與synchronized的差別,以下尾隨LZ的筆記來扒扒ReentrantLock的lock方法。我們知道ReentrantLock有公平鎖、非

J.U.C之AQSCLH同步佇列

此篇部落格所有原始碼均來自JDK 1.8 在上篇部落格中提到了AQS內部維護著一個FIFO佇列,該佇列就是CLH同步佇列。 CLH同步佇列是一個FIFO雙向佇列,AQS依賴它來完成同步狀態的管理,當前執行緒如果獲取同步狀態失敗時,AQS則會將當前執行緒已經等待狀態等資

死磕Java併發J.U.C之AQSCLH同步佇列

本文轉載自公號:Java技術驛站在上篇文章中提到了AQS內部維護著一個FIFO佇列,該佇列就是C

【死磕Java併發】-----J.U.C之AQSCLH同步佇列

此篇部落格所有原始碼均來自JDK 1.8 CLH同步佇列是一個FIFO雙向佇列,AQS依賴它來完成同步狀態的管理,當前執行緒如果獲取同步狀態失敗時,AQS則會將當前執行緒已經等待狀態等資訊構造成一個節點(Node)並將其加入到CLH同步佇列,同時會

慕課網實戰·高併發探索(十二)併發容器J.U.C -- AQS元件 ReentrantLock、ReentrantReadWriteLock、StempedLock

特別感謝:慕課網jimin老師的《Java併發程式設計與高併發解決方案》課程,以下知識點多數來自老師的課程內容。 jimin老師課程地址:Java併發程式設計與高併發解決方案 ReentrantLock java中有兩類鎖,一類是Synchron

J.U.C重入

itl 數據 cnblogs 執行 ont 微軟 nds asq jpg ReentrantLock重入鎖 ReentrantLock是Java並發包中互斥鎖,它有公平鎖和非公平鎖兩種實現方式, 重入的意思就是,如果已經獲得了鎖,如果執行期間還需要

J.U.C之AQS阻塞和喚醒線程

smart -i back ont () 而不是 受限 clh blog 此篇博客所有源碼均來自JDK 1.8 在線程獲取同步狀態時如果獲取失敗,則加入CLH同步隊列,通過通過自旋的方式不斷獲取同步狀態,但是在自旋的過程中則需要判斷當前線程是否需要阻塞,其主要方法在ac

J.U.C之AQS同步狀態的獲取與釋放

unpark 超時時間 DC 後繼節點 thum AD 方式 dea b-s 此篇博客所有源碼均來自JDK 1.8 在前面提到過,AQS是構建Java同步組件的基礎,我們期待它能夠成為實現大部分同步需求的基礎。AQS的設計模式采用的模板方法模式,子類通過繼承的方式,實現

J.U.C原始碼分析CountDownLatch

        CountDownLoad是在併發程式設計中使用較多的一個類,可以完成多個執行緒之間的相互等待和協作,原始碼內容不多但功能強大且使用場景複雜多樣。         原始碼

Java多執行緒進階(三七)—— J.U.C之collections框架LinkedBlockingDeque

一、LinkedBlockingDeque簡介 LinkedBlockingDeque和ConcurrentLinkedDeque類似,都是一種雙端佇列的結構,只不過LinkedBlockingDeque同時也是一種阻塞佇列,它是在JDK1.5時隨著J.U.C包引

Java多執行緒進階(三八)—— J.U.C之collections框架LinkedTransferQueue

一、LinkedTransferQueue簡介 LinkedTransferQueue是在JDK1.7時,J.U.C包新增的一種比較特殊的阻塞佇列,它除了具備阻塞佇列的常用功能外,還有一個比較特殊的transfer方法。 我們知道,在普通阻塞佇列中,當佇列為空時,

高併發第十三彈:J.U.C 佇列 SynchronousQueue.ArrayBlockingQueue.LinkedBlockingQueue.LinkedTransferQueue

因為下一節會說執行緒池,要用執行緒池 那麼執行緒池有個很重要的引數 就是Queue的選擇 常用的佇列其實就兩種:   先進先出(FIFO):先插入的佇列的元素也最先出佇列,類似於排隊的功能。從某種程度上來說這種佇列也體現了一種公平性。  後進先出(LIFO):後插入佇列的元素最先出佇列,這種佇列優先處理最近發

J.U.C 之 AQS同步狀態的獲取與釋放

在前面提到過,AQS 是構建 Java 同步元件的基礎,我們期待它能夠成為實現大部分同步需求的基礎。 AQS 的設計模式採用的模板方法模式,子類通過繼承的方式,實現它的抽象方法來管理同步狀態。對於子類而言,它並沒有太多的活要做,AQS 已經提供了大量的模板方法來實現同步