CLH同步佇列

2022-02-19 20:25:40 字數 1350 閱讀 5718

aqs內部維護著乙個fifo佇列,該佇列就是clh同步佇列。

clh同步佇列是乙個fifo雙向佇列,aqs依賴它來完成同步狀態的管理,當前執行緒如果獲取同步狀態失敗時,aqs則會將當前執行緒已經等待狀態等資訊構造成乙個節點(node)並將其加入到clh同步佇列,同時會阻塞當前執行緒,當同步狀態釋放時,會把首節點喚醒(公平鎖),使其再次嘗試獲取同步狀態。

在clh同步佇列中,乙個節點表示乙個執行緒,它儲存著執行緒的引用(thread)、狀態(waitstatus)、前驅節點(prev)、後繼節點(next),其定義如下:

static

final

class

node

final node predecessor() throws

nullpointerexception

node()

node(thread thread, node mode)

node(thread thread,

intwaitstatus)

}

clh同步佇列結構圖如下:

學了資料結構的我們,clh隊列入列是再簡單不過了,無非就是tail指向新節點、新節點的prev指向當前最後的節點,當前最後乙個節點的next指向當前節點。**我們可以看看addwaiter(node node)方法:

private

node addwaiter(node mode)

}//多次嘗試

enq(node);

return

node;

}

addwaiter(node node)先通過快速嘗試設定尾節點,如果失敗,則呼叫enq(node node)方法設定尾節點

private node enq(final

node node)

else}}

}

在上面**中,兩個方法都是通過乙個cas方法compareandsettail(node expect, node update)來設定尾節點,該方法可以確保節點是執行緒安全新增的。在enq(node node)方法中,aqs通過「死迴圈」的方式來保證節點可以正確新增,只有成功新增後,當前執行緒才會從該方法返回,否則會一直執行下去。

過程圖如下: 

clh同步佇列遵循fifo,首節點的執行緒釋放同步狀態後,將會喚醒它的後繼節點(next),而後繼節點將會在獲取同步狀態成功時將自己設定為首節點,這個過程非常簡單,head執行該節點並斷開原首節點的next和當前節點的prev即可,注意在這個過程是不需要使用cas來保證的,因為只有乙個執行緒能夠成功獲取到同步狀態。過程圖如下:

CLH同步佇列是怎麼實現非公平和公平的

the wait queue is a variant of a clh craig,landin,and hagersten lock queue.clh locks are normally used for spinlocks 1 名稱 clh 由三個人名字組成 craig,landin,an...

執行緒程式設計 同步佇列

我們經常會採用生產者 消費者關係的兩個執行緒來處理乙個共享緩衝區的資料。例如一 個生產者執行緒接受使用者資料放入乙個共享緩衝區裡,等待乙個消費者執行緒對資料取出處理。但是如果緩衝區的太小而生產者和消費者兩個非同步執行緒的速度不同時,容 易出現乙個執行緒等待另乙個情況。為了盡可能的縮短共享資源並以相同...

(原創)C 同步佇列

同步佇列作為乙個執行緒安全的資料共享區,經常用於執行緒之間資料讀取,比如半同步半非同步執行緒池的同步佇列。其實做起來比較簡單,要用到list 鎖和條件變數,條件變數的作用是在佇列滿了或者空了的時候等待通知。先看乙個簡單的同步佇列 include include include include inc...