CyclicBarrier實現原理核心邏輯

2021-10-06 17:07:42 字數 2925 閱讀 5824

cyclicbarrier作用:

cyclicbarrier用於同步一組執行緒,建立cyclicbarrier時指定參與迴圈柵欄的執行緒數量與一組執行緒全部就位時,優先執行的動作。 每個執行緒呼叫await()方法後,即表示到達柵欄點,然後就會進阻塞,當參與迴圈柵欄的最後乙個執行緒呼叫了await()方法後,會喚醒之前阻塞的執行緒,迴圈柵欄重置,進入下一次迴圈。

cyclicbarrier欄位解釋:

//	表示本次迴圈的狀態:為true時,表示本次迴圈被破壞(如,有執行緒被中斷、await超時)

private

static

class

generation

/** 在執行await時是獨佔的 */

private

final reentrantlock lock =

newreentrantlock()

;/** 用於多個執行緒之間的同步 */

private

final condition trip = lock.

newcondition()

;/** 參與一次迴圈的執行緒數 */

private

final

int parties;

/* 所有都達到迴圈柵欄點時,優先執行的動作 */

private

final runnable barriercommand;

/** the current generation */

private generation generation =

newgeneration()

;/** 用來表示當前剩餘的需要到達柵欄點的執行緒數量 **/

private

int count;

cyclicbarrier核心邏輯的實現:dowait(boolean timed, long nanos)。

當呼叫await方法後,最後會呼叫 dowait(boolean timed, long nanos)。

執行流程:

首次明確這個過程需要加鎖,因為會涉及到多個共享變數的賦值與執行緒之間的同步。

拿到鎖後,先檢查本次迴圈的狀態是否被破壞,若被破壞則直接丟擲異常。

然後檢查當前執行緒是否被中斷,若被中斷呼叫breakbarrier()去終止本次迴圈:將迴圈狀態置為無效狀態,將剩餘需要到達柵欄點的執行緒數置為初始值,最後喚醒所以呼叫await進入阻塞狀態的執行緒。breakbarrier()執行完畢後丟擲中斷異常。

檢查通過的話,將需要進入柵欄點的執行緒數減一(–count)

減完後的值若為0:代表本次迴圈執行完畢,此時若建立cyclicbarrier時指定了到達柵欄點需要執行的任務,則先執行該任務,然後呼叫nextgeneration()去更新狀態,為下一次迴圈初始化: 先喚醒所有等待的執行緒,將count設定為初始值parties,新建乙個generation賦值給generation變數。

如果–count後的值不為0,則代表還有執行緒未準備就緒,則進入阻塞過程,阻塞過程發生中斷呼叫breakbarrier()。當從阻塞狀態被喚醒後,會檢查當前代(generation)是否被破壞,破壞直接丟擲柵欄被破壞。未被破壞,檢查是否正常換代,即檢查進入await方法時拿到的 generation的引用(g)與現在的generation還是否是同乙個?在–count為0時,執行了nextgeneration()方法,該方法會新建乙個generation賦值給generation變數。所以在這裡如果g!=generation代表成功換代。

參照原始碼理解上述過程:

private

intdowait

(boolean timed,

long nanos)

throws interruptedexception, brokenbarrierexception,

timeoutexception

// 獲取下標

int index =

--count;

// 如果是 0,說明最後乙個執行緒呼叫了該方法

if(index ==0)

finally

}// loop until tripped, broken, interrupted, or timed out

for(;;

)catch

(interruptedexception ie)

else

}// 當有任何乙個執行緒中斷了,就會呼叫breakbarrier方法

// 就會喚醒其他的執行緒,其他執行緒醒來後,也要丟擲異常

if(g.broken)

throw

newbrokenbarrierexception()

;// g != generation表示正常換代了,返回當前執行緒所在柵欄的下標

// 如果 g == generation,說明還沒有換代,那為什麼會醒了?

// 因為乙個執行緒可以使用多個柵欄,當別的柵欄喚醒了這個執行緒,就會走到這裡,所以需要判斷是否是當前代。

// 正是因為這個原因,才需要generation來保證正確。

if(g != generation)

return index;

// 如果有時間限制,且時間小於等於0,銷毀柵欄並丟擲異常

if(timed && nanos <=

0l)}

}finally

}

讓當前柵欄失效:

private

void

breakbarrier()

進行換代:

private

void

nextgeneration()

CyclicBarrier實現原理

cyclicbarrier是乙個同步輔助類,它允許一組執行緒互相等待,直到所有執行緒都到達某個公共屏障點 也可以叫同步點 即相互等待的執行緒都完成呼叫await方法,所有被屏障攔截的執行緒才會繼續執行await方法後面的程式。在涉及一組固定大小的執行緒的程式中,這些執行緒必須不時地互相等待,此時cy...

CyclicBarrier 同步屏障實現分析

cyclicbarrier 是可迴圈使用的屏障,主要功能是讓一組執行緒到達乙個屏障時被阻塞,直到最後乙個執行緒到達屏障時,屏障才會開啟 所有被屏障攔截的執行緒才會繼續執行。使用示例public class cyclicbarriertest catch interruptedexception e ...

同步屏障CyclicBarrier

cyclicbarrier操作excel public class bankwaterservice implements runnable private void count throws exception 計算當前sheet的銀流資料,計算 省略 sheetbankwatercount.pu...