在前面介紹的幾篇博客中總是提到CLH隊(duì)列,在AQS中CLH隊(duì)列是維護(hù)一組線程的嚴(yán)格按照FIFO的隊(duì)列。他能夠確保無饑餓,嚴(yán)格的先來先服務(wù)的公平性。下圖是CLH隊(duì)列節(jié)點(diǎn)的示意圖:
在CLH隊(duì)列的節(jié)點(diǎn)QNode中包含有一個(gè)locked的字段,該字段表示該節(jié)點(diǎn)是否需要獲取鎖,為true表示需要獲取,為false表示不需要獲取。在CLH隊(duì)列中,節(jié)點(diǎn)與節(jié)點(diǎn)之間并不是通過next指針來連接的而是通過myPRed所指向節(jié)點(diǎn)的變化情況來影響的myNode的行為。
假設(shè)有兩個(gè)線程(線程A、線程B)。開始線程A需要獲得鎖,那么他會(huì)創(chuàng)建一個(gè)QNode節(jié)點(diǎn),并將locked設(shè)置為true(表示需要獲取鎖),同時(shí)獲取一個(gè)指向前驅(qū)的myPred并在前驅(qū)節(jié)點(diǎn)的的locked上面旋轉(zhuǎn)直到前驅(qū)節(jié)點(diǎn)是否鎖為止(locked為false,這個(gè)動(dòng)作我們一般稱之為自旋),當(dāng)然這里會(huì)將tail指向自身來表示它是CLH隊(duì)列的最后一個(gè)節(jié)點(diǎn),如下:
然后線程B添加到CLH隊(duì)列中,這時(shí)tail域應(yīng)該指向線程B。
CLH隊(duì)列鎖的優(yōu)點(diǎn)在于空間復(fù)雜度低(如果有n個(gè)線程,L個(gè)鎖,每個(gè)線程每次只獲取一個(gè)鎖,那么需要的存儲(chǔ)空間是O(L+n),n個(gè)線程有n個(gè)myNode,L個(gè)鎖有L個(gè)tail)。CLH的變種體被運(yùn)用到了AQS中。
參考文獻(xiàn)
java并發(fā)編程學(xué)習(xí)筆記之CLH隊(duì)列鎖:http://blog.csdn.net/aesop_wubo/article/details/7533186
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注