JAVA并發(fā)之CyclicBarrier

今天過生日啦义辕,今年的生日比往年晚一些(閏了個四月)又漲一歲历谍,29啦现拒。
晚上閑著讀會CyclickBarrier代碼,中文意思翻譯過來叫循環(huán)柵欄望侈,顧名思義我們可以理解為賽馬跑圈具练,不過有點(diǎn)特色就是這些賽馬可以一圈又一圈的跑。并且所有馬跑完再進(jìn)行下一圈。
先寫一個小程序把玩一下吧。
程序目的如下:
我們模擬一個學(xué)校假設(shè)有三個班級及刻,每個班級有5個學(xué)生,同學(xué)們出了期末成績陵究,我們希望通過三個人(線程)幫我排序每個班學(xué)生的成績,順便就用冒泡做個簡單實(shí)現(xiàn)吧奥帘。就用最粗暴的雙層循環(huán)不做優(yōu)化铜邮,因?yàn)閮?yōu)化的話其實(shí)冒泡排序還能做一些有序邊界的優(yōu)化,此文不做探討,還請各位看官輕噴松蒜。
talk is cheap 扔茅,show me the code

/**
 * @author guozc
 *
 * 2020年7月1日
 */
public class CyclicBarrierTest {
        private static int[] chengji = new int[15];
        static  class TaskThread extends Thread {
        
            CyclicBarrier barrier;
            int beginIndex;
            int endIndex;
            public TaskThread(CyclicBarrier barrier, int beginIndex) {
                this.barrier = barrier;
                this.beginIndex = beginIndex;
                this.endIndex = beginIndex + 5;
            }
            
            @Override
            public void run() {
                try {
                    for(int t = 1; t < 6; t++) {
                        for(int i = beginIndex; i < endIndex-1; i++) {
                            if (chengji[i] > chengji[i + 1]) {
                                int temp =  chengji[i + 1];
                                chengji[i + 1] = chengji[i];
                                chengji[i] = temp;
                            }
                                
                        }
                        System.out.println(Thread.currentThread().getName() +"完成了第" + t +"次排序");
                        barrier.await();
                    }
                    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        
        public static void main(String[] args) {
            Random random = new Random();
            for (int i = 0; i < 15; i++) {
                chengji[i] = random.nextInt(50)+50;
            }
            System.out.println("原始成績"+Arrays.toString(chengji));
            CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
                int times = 1;
                @Override
                public void run() {
                    System.out.println("執(zhí)行完第" + times+"次");
                    System.out.println(Arrays.toString(chengji));
                    times++;
                }
            });
            
            for(int i = 0; i < 3; i++) {
                new TaskThread(cyclicBarrier,i*5).start();
            }
           
        }
}

初始化一個容量為3的循環(huán)柵欄,外加一個全班級成績的隨機(jī)數(shù)組秸苗,main方法入口一開始初始化這15個人的成績召娜,然后我們?nèi)藶榈姆譃槿M,交給每個線程不同的分段去操作屬于自己的班級成績惊楼,通過冒泡排序進(jìn)行成績排名玖瘸。為了方便演示阻塞效果我們在每次冒泡排完一次就輸出一下當(dāng)前線程名字并在線程內(nèi)部初始化了一個統(tǒng)計變量讓輸出更加清晰
代碼執(zhí)行結(jié)果如下


微信圖片_20200701222130.png

一開始分了三組也就是結(jié)果的第一行原始成績單,因?yàn)槭请S機(jī)的所以是無序的檀咙,通過每個線程撞第一次柵欄前的運(yùn)算我們看到第一次執(zhí)行結(jié)果雅倒,每一組的最后一個變成了最大的,依次類推完全符合冒泡排序的規(guī)律弧可,直接看最后依次蔑匣,我們看到每一組我順序都是從小到大進(jìn)行展示的。符合我們的預(yù)期棕诵。
在日常開發(fā)中殖演,循環(huán)柵欄一般用于并發(fā)運(yùn)算,比如我們稍微改一下這個場景年鸳,要求計算每個班級總分?jǐn)?shù),或者平均分?jǐn)?shù)丸相,那么久可以開啟三個線程去執(zhí)行搔确,當(dāng)然這么用有點(diǎn)小題大做了,因?yàn)橛嬎沩樞蚝芸烀鹬遥瑪?shù)據(jù)量又小所以可能還不如單線程快膳算。但是這部妨礙我們理解這個模型。因?yàn)檫@種結(jié)論本身是一個在什么場景下適合使用多線程提升效率的問題弛作。
一般來講涕蜂,線程有效執(zhí)行時間超過線程切換的時間時候基本就適合使用多線程進(jìn)行并行處理。

跟CountDownLatch在這里做一個簡單對比

一映琳、昨天分析的CountDownLatch它是一個用于倒計數(shù)控制的机隙,它側(cè)重在不同任務(wù)的并行處理,(生產(chǎn)門子萨西,生產(chǎn)輪胎有鹿,生產(chǎn)把手)最后組裝成車而CyclicBarrier往往更多用在并行的相同任務(wù)的處理。

二谎脯、CountDownLatch是一次性的葱跋,而CyclicBarrier是可循環(huán)使用的,這里面有個小細(xì)節(jié),CyclicBarrier其實(shí)是通過每個子線程去撞柵欄完成的generation的改變(這部分源碼明天再補(bǔ)充)娱俺。所以會要求分線程執(zhí)行任務(wù)比較對齊稍味。這也跟上一點(diǎn)相呼應(yīng)。

三荠卷、CyclicBarrier每次換代時候都會調(diào)用在初始化CyclicBarrier 傳入的Runnable類型的參數(shù)模庐,也就是源碼里面的command參數(shù)。有點(diǎn)Map reduce的趕腳哈僵朗。這種撞柵欄的感覺有點(diǎn)JVM在做GC時候的saftPoint(安全點(diǎn))的趕腳赖欣,不展開了有興趣的哥們可以期待小弟的JVM相關(guān)文檔,慢慢都會寫一些


時間不早洗洗睡各位有不同意見還請多多留言验庙,共同進(jìn)步
源碼分析待補(bǔ)充

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末顶吮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子粪薛,更是在濱河造成了極大的恐慌悴了,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件违寿,死亡現(xiàn)場離奇詭異湃交,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)藤巢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門搞莺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人掂咒,你說我怎么就攤上這事才沧。” “怎么了绍刮?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵温圆,是天一觀的道長。 經(jīng)常有香客問我孩革,道長岁歉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任膝蜈,我火速辦了婚禮锅移,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘饱搏。我一直安慰自己帆啃,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布窍帝。 她就那樣靜靜地躺著努潘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上疯坤,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天报慕,我揣著相機(jī)與錄音,去河邊找鬼压怠。 笑死眠冈,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的菌瘫。 我是一名探鬼主播蜗顽,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼雨让!你這毒婦竟也來了雇盖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤栖忠,失蹤者是張志新(化名)和其女友劉穎崔挖,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體庵寞,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡狸相,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了捐川。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脓鹃。...
    茶點(diǎn)故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖古沥,靈堂內(nèi)的尸體忽然破棺而出瘸右,到底是詐尸還是另有隱情,我是刑警寧澤渐白,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站逞频,受9級特大地震影響纯衍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苗胀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一襟诸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧基协,春花似錦歌亲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春悍缠,著一層夾襖步出監(jiān)牢的瞬間卦绣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工飞蚓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留滤港,地道東北人。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓趴拧,卻偏偏與公主長得像溅漾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子著榴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評論 2 354