CyclicBarrier

循環(huán)屏障,它允許多個線程相互等待到一個障礙點之后才繼續(xù)執(zhí)行,可指定等待到屏障之后的執(zhí)行任務(wù),CyclicBarrier支持循環(huán)使用绍妨。

功能說明

CyclicBarrier實現(xiàn)了當(dāng)多個線程達(dá)到屏障之后才執(zhí)行的功能,可指定runable表示達(dá)到屏障之后執(zhí)行的任務(wù)柬脸。類似于CountDownLatch的功能他去。但是與CountDownLatch不同的是,CyclicBarrier可以通過reset方法重置進(jìn)行重復(fù)使用倒堕,所以Cyclicbarries適合更加復(fù)雜的場景灾测,例如可以實現(xiàn)執(zhí)行錯誤之后通過reset重試。

CyclicBarrier(int parties, Runnable barrierAction)//屏障數(shù)和等待后任務(wù)

使用場景

1垦巴、 實現(xiàn)多線程任務(wù)執(zhí)行完后的匯總媳搪。barrierAction表示匯總操作。

實現(xiàn)關(guān)鍵

 private int dowait(boolean timed, long nanos)
       throws InterruptedException, BrokenBarrierException,
              TimeoutException {
       final ReentrantLock lock = this.lock;
       lock.lock();//每次嗲用await都需要獲取lock鎖
       try {
           final Generation g = generation;

           if (g.broken)//如果當(dāng)前代broken
               throw new BrokenBarrierException();

           if (Thread.interrupted()) {//如果線程被中中斷骤宣,則breakBarriers秦爆,屏障將會不可用,除非調(diào)用reset開始新代
               breakBarrier();
               throw new InterruptedException();
           }

           int index = --count;
           if (index == 0) {  // 如果當(dāng)前時最后一個到達(dá)屏障的線程憔披,執(zhí)行runnable等限,并且開啟新的代爸吮,喚醒所有等待的線程
               boolean ranAction = false;
               try {
                   final Runnable command = barrierCommand;
                   if (command != null)
                       command.run();
                   ranAction = true;
                   nextGeneration();
                   return 0;
               } finally {
                   if (!ranAction)//如果runnable執(zhí)行失敗,也會breakBarrier屏障
                       breakBarrier();
               }
           }

           // loop until tripped, broken, interrupted, or timed out
           for (;;) {//不是最后一個到達(dá)屏障的線程望门,通過condition進(jìn)入等待形娇,直到被觸發(fā)、broken怒允、中斷埂软、超時
               try {
                   if (!timed)
                       trip.await();
                   else if (nanos > 0L)
                       nanos = trip.awaitNanos(nanos);
               } catch (InterruptedException ie) {
                   if (g == generation && ! g.broken) {
                       breakBarrier();
                       throw ie;
                   } else {
                       // We're about to finish waiting even if we had not
                       // been interrupted, so this interrupt is deemed to
                       // "belong" to subsequent execution.
                       Thread.currentThread().interrupt();
                   }
               }

               if (g.broken)
                   throw new BrokenBarrierException();

               if (g != generation)//表示開始新的代了  
                   return index;

               if (timed && nanos <= 0L) {
                   breakBarrier();
                   throw new TimeoutException();
               }
           }
       } finally {
           lock.unlock();
       }
   }

1、調(diào)用await方法的線程表示線程到達(dá)了屏障纫事。
2、是否全部到達(dá)屏障通過count來判斷所灸,因為涉及到多線程同步問題丽惶,所以內(nèi)部使用了ReenTrantLock來同步代碼。
3爬立、如果線程被中斷钾唬,那么會breakBarrier,屏障不可用了侠驯,并且喚醒所有等待的線程抡秆。
4、當(dāng)count為0時吟策,表示全部到達(dá)屏障了儒士,將執(zhí)行設(shè)置的runnable。然后開啟下一代檩坚,喚醒所有等待的線程着撩。如果執(zhí)行runnable失敗,則也會breakBarrier匾委。
5拖叙、否則表示不是最后一個到達(dá)屏障的線程,會通過condition來堵塞線程赂乐。直到最后一個線程執(zhí)行完之后喚醒或者超時薯鳍、中斷。

總結(jié)

CyclicBarrier通過一個count值來表示剩余到達(dá)屏障的線程挨措,由于涉及到并發(fā)操作挖滤,所以通過ReenTrantLock來實現(xiàn)同步,當(dāng)線程執(zhí)行await時运嗜,如果不是最后一個到達(dá)屏障的線程壶辜,那么會通過Condition來堵塞線程,當(dāng)count等于0時担租,表示最后一個到達(dá)屏障的線程砸民,將會喚醒等待中的線程。CyclicBarrier支持循環(huán)利用是因為其中引入了一個generation一代的概念,當(dāng)一代執(zhí)行完將開啟新的代(其實就是將數(shù)據(jù)重置了)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末岭参,一起剝皮案震驚了整個濱河市反惕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌演侯,老刑警劉巖姿染,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異秒际,居然都是意外死亡悬赏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門娄徊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闽颇,“玉大人,你說我怎么就攤上這事寄锐”啵” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵橄仆,是天一觀的道長剩膘。 經(jīng)常有香客問我,道長盆顾,這世上最難降的妖魔是什么怠褐? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮椎扬,結(jié)果婚禮上惫搏,老公的妹妹穿的比我還像新娘。我一直安慰自己蚕涤,他們只是感情好筐赔,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著揖铜,像睡著了一般茴丰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上天吓,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天贿肩,我揣著相機與錄音,去河邊找鬼龄寞。 笑死汰规,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的物邑。 我是一名探鬼主播溜哮,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼滔金,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了茂嗓?” 一聲冷哼從身側(cè)響起餐茵,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎述吸,沒想到半個月后忿族,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蝌矛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年道批,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片朴读。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡屹徘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衅金,到底是詐尸還是另有隱情,我是刑警寧澤簿煌,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布氮唯,位于F島的核電站,受9級特大地震影響姨伟,放射性物質(zhì)發(fā)生泄漏惩琉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一夺荒、第九天 我趴在偏房一處隱蔽的房頂上張望瞒渠。 院中可真熱鬧,春花似錦技扼、人聲如沸伍玖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窍箍。三九已至,卻和暖如春丽旅,著一層夾襖步出監(jiān)牢的瞬間椰棘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工榄笙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留邪狞,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓茅撞,卻偏偏與公主長得像帆卓,于是被迫代替她去往敵國和親巨朦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容