pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

Java中CyclicBarrier?循環(huán)屏障

這篇文章主要介紹了Java中CyclicBarrier?循環(huán)屏障,可以實(shí)現(xiàn)讓一組線程等待至某個(gè)狀態(tài)屏障點(diǎn)之后再全部同時(shí)執(zhí)行,下面文章分享CyclicBarrier循環(huán)屏障的原理,需要的小伙伴可以參考一下

一、簡介

CyclicBarrier 字面意思回環(huán)柵欄(循環(huán)屏障),它可以實(shí)現(xiàn)讓一組線程等待至某個(gè)狀態(tài)(屏障點(diǎn))之后再全部同時(shí)執(zhí)行。叫做回環(huán)是因?yàn)楫?dāng)所有等待線程都被釋放以后,CyclicBarrier可以被重用。 

CyclicBarrier 作用是讓一組線程相互等待,當(dāng)達(dá)到一個(gè)共同點(diǎn)時(shí),所有之前等待的線程再繼續(xù)執(zhí)行,且 CyclicBarrier 功能可重復(fù)使用。

二、CyclicBarrier的使用

構(gòu)造方法:

?// parties表示屏障攔截的線程數(shù)量,每個(gè)線程調(diào)用 await 方法告訴 CyclicBarrier 我已經(jīng)到達(dá)了屏障,然后當(dāng)前線程被阻塞。
 public CyclicBarrier(int parties)
 // 用于在線程到達(dá)屏障時(shí),優(yōu)先執(zhí)行 barrierAction,方便處理更復(fù)雜的業(yè)務(wù)場景(該線程的執(zhí)行時(shí)機(jī)是在到達(dá)屏障之后再執(zhí)行)

重要方法:

//屏障 指定數(shù)量的線程全部調(diào)用await()方法時(shí),這些線程不再阻塞
// BrokenBarrierException 表示柵欄已經(jīng)被破壞,破壞的原因可能是其中一個(gè)線程 await() 時(shí)被中斷或者超時(shí)
public int await() throws InterruptedException, BrokenBarrierException
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
//循環(huán)  通過reset()方法可以進(jìn)行重置

CyclicBarrier 應(yīng)用場景

  • 利用 CyclicBarrier 可以用于多線程計(jì)算數(shù)據(jù),最后合并計(jì)算結(jié)果的場景。
  • 利用 CyclicBarrier的計(jì)數(shù)器能夠重置,屏障可以重復(fù)使用的特性,可以支持類似“人滿發(fā)車”的場景

模擬合并計(jì)算場景

利用 CyclicBarrier 可以用于多線程計(jì)算數(shù)據(jù),最后合并計(jì)算結(jié)果的場景。

public class CyclicBarrierTest2 {
    //保存每個(gè)學(xué)生的平均成績
    private Conc urrentHashMap<String, Integer> map=new ConcurrentHashMap<String,Integer>();
    private ExecutorService threadPool= Executors.newFixedThreadPool(3);
    private CyclicBarrier cb=new CyclicBarrier(3,()->{
        int result=0;
        Set<String> set = map.keySet();
        for(String s:set){
            result+=map.get(s);
        }
        System.out.println("三人平均成績?yōu)?"+(result/3)+"分");
    });
    public void count(){
        for(int i=0;i<3;i++){
            threadPool.execute(new Runnable(){

                @Override
                public void run() {
                    //獲取學(xué)生平均成績
                    int score=(int)(Math.random()*40+60);
                    map.put(Thread.currentThread().getName(), score);
                    System.out.println(Thread.currentThread().getName()
                            +"同學(xué)的平均成績?yōu)椋?+score);
                    try {
                        //執(zhí)行完運(yùn)行await(),等待所有學(xué)生平均成績都計(jì)算完畢
                        cb.await();
                    } catch (InterruptedException | BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }

            });
        }
    }
    public static void main(String[] args) {
        CyclicBarrierTest2 cb=new CyclicBarrierTest2();
        cb.count();
    }
}

模擬“人滿發(fā)車”的場景

利用CyclicBarrier的計(jì)數(shù)器能夠重置,屏障可以重復(fù)使用的特性,可以支持類似“人滿發(fā)車”的場景

public class CyclicBarrierTest3 {
    public static void main(String[] args) {
        AtomicInteger counter = new AtomicInteger();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                5, 5, 1000, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(100),
                (r) -> new Thread(r, counter.addAndGet(1) + " 號 "),
                new ThreadPoolExecutor.AbortPolicy());

        CyclicBarrier cyclicBarrier = new CyclicBarrier(5,
                () -> System.out.println("裁判:比賽開始~~"));

        for (int i = 0; i < 10; i++) {
            threadPoolExecutor.submit(new Runner(cyclicBarrier));
        }

    }
    static class Runner extends Thread{
        private CyclicBarrier cyclicBarrier;
        public Runner (CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }
        @Override
        public void run() {
            try {
                int sleepMills = ThreadLocalRandom.current().nextInt(1000);
                Thread.sleep(sleepMills);
                System.out.println(Thread.currentThread().getName() + " 選手已就位, 準(zhǔn)備共用時(shí): " + sleepMills + "ms" + cyclicBarrier.getNumberWaiting());
                cyclicBarrier.await();

            } catch (InterruptedException e) {
                e.printStackTrace();
            }catch(BrokenBarrierException e){
                e.printStackTrace();
            }
        }
    }

}

輸出結(jié)果:

3 號  選手已就位, 準(zhǔn)備共用時(shí): 78ms0
1 號  選手已就位, 準(zhǔn)備共用時(shí): 395ms1
5 號  選手已就位, 準(zhǔn)備共用時(shí): 733ms2
2 號  選手已就位, 準(zhǔn)備共用時(shí): 776ms3
4 號  選手已就位, 準(zhǔn)備共用時(shí): 807ms4
裁判:比賽開始~~
4 號  選手已就位, 準(zhǔn)備共用時(shí): 131ms0
3 號  選手已就位, 準(zhǔn)備共用時(shí): 256ms1
2 號  選手已就位, 準(zhǔn)備共用時(shí): 291ms2
1 號  選手已就位, 準(zhǔn)備共用時(shí): 588ms3
5 號  選手已就位, 準(zhǔn)備共用時(shí): 763ms4
裁判:比賽開始~~

三、CyclicBarrier 源碼分析

CyclicBarrier 流程

主要是的流程:

  • 獲取鎖 如果 count != 0 就進(jìn)入阻塞;
  • 進(jìn)入阻塞之前,首先需要進(jìn)入條件隊(duì)列,然后釋放鎖,最后阻塞;
  • 如果 count != 0 會進(jìn)行一個(gè)喚醒,將所有的條件隊(duì)列中的節(jié)點(diǎn)轉(zhuǎn)換為阻塞隊(duì)列;
  • 被喚醒過后會進(jìn)行鎖的獲取,如果鎖獲取失敗,會進(jìn)入 lock 的阻塞隊(duì)列;
  • 如果鎖獲取成功,進(jìn)行鎖的釋放,以及喚醒,同步隊(duì)列中的線程。

下面是一個(gè)簡單的流程圖:

下面是具體的一些代碼調(diào)用的流程:

幾個(gè)常見的問題?

  • 1.一組線程在觸發(fā)屏障之前互相等待,最后一個(gè)線程到達(dá)屏障后喚醒邏輯是如何實(shí)現(xiàn)的. 喚醒的過程是通過調(diào)用 java.util.concurrent.locks.Condition#signalAll喚醒條件隊(duì)列上的所有節(jié)點(diǎn)。
  • 2.刪欄循環(huán)使用是如何實(shí)現(xiàn)的? 實(shí)際上一個(gè)互斥鎖 ReentrantLock 的條件隊(duì)列和阻塞隊(duì)列的轉(zhuǎn)換。
  • 3.條件隊(duì)列到同步隊(duì)列的轉(zhuǎn)換實(shí)現(xiàn)邏輯 ? 轉(zhuǎn)換過程中,首先會先將條件隊(duì)列中所有的阻塞線程喚醒,然后會去獲取 lock 如果獲取失敗,就進(jìn)入同步隊(duì)列。

CyclicBarrier 與 CountDownLatch的區(qū)別

  • CountDownLatch的計(jì)數(shù)器只能使用一次,而CyclicBarrier的計(jì)數(shù)器可以使用reset() 方法重置。所以CyclicBarrier能處理更為復(fù)雜的業(yè)務(wù)場景,比如如果計(jì)算發(fā)生錯(cuò)誤,可以重置計(jì)數(shù)器,并讓線程們重新執(zhí)行一次
  • CyclicBarrier還提供getNumberWaiting(可以獲得CyclicBarrier阻塞的線程數(shù)量)、isBroken(用來知道阻塞的線程是否被中斷)等方法。
  • CountDownLatch會阻塞主線程,CyclicBarrier不會阻塞主線程,只會阻塞子線程。
  • CountDownLatch和CyclicBarrier都能夠?qū)崿F(xiàn)線程之間的等待,只不過它們側(cè)重點(diǎn)不同。CountDownLatch一般用于一個(gè)或多個(gè)線程,等待其他線程執(zhí)行完任務(wù)后,再執(zhí)行。CyclicBarrier一般用于一組線程互相等待至某個(gè)狀態(tài),然后這一組線程再同時(shí)執(zhí)行。
  • CyclicBarrier 還可以提供一個(gè) barrierAction,合并多線程計(jì)算結(jié)果。
  • CyclicBarrier是通過ReentrantLock的"獨(dú)占鎖"和Conditon來實(shí)現(xiàn)一組線程的阻塞喚醒的,而CountDownLatch則是通過AQS的“共享鎖”實(shí)現(xiàn)

到此這篇關(guān)于Java中CyclicBarrier 循環(huán)屏障的文章就介紹到這了,更多相關(guān)Java CyclicBarrier 內(nèi)容請搜索html5模板網(wǎng)以前的文章希望大家以后多多支持html5模板網(wǎng)!

【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

主站蜘蛛池模板: 深圳市东信高科自动化设备有限公司 | 蒸压釜-陶粒板隔墙板蒸压釜-山东鑫泰鑫智能装备有限公司 | 吹田功率计-长创耐压测试仪-深圳市新朗普电子科技有限公司 | 郑州外墙清洗_郑州玻璃幕墙清洗_郑州开荒保洁-河南三恒清洗服务有限公司 | 机构创新组合设计实验台_液压实验台_气动实训台-戴育教仪厂 | Pos机办理_个人商户免费POS机申请-拉卡拉办理网 | 热处理炉-退火炉-回火炉设备厂家-丹阳市电炉厂有限公司 | 玻纤土工格栅_钢塑格栅_PP焊接_单双向塑料土工格栅_复合防裂布厂家_山东大庚工程材料科技有限公司 | 重庆私家花园设计-别墅花园-庭院-景观设计-重庆彩木园林建设有限公司 | 昆明化妆培训-纹绣美甲-美容美牙培训-昆明博澜培训学校 | 安全光栅|射频导纳物位开关|音叉料位计|雷达液位计|两级跑偏开关|双向拉绳开关-山东卓信机械有限公司 | 防爆鼓风机-全风-宏丰鼓风机-上海梁瑾机电设备有限公司 | 尾轮组_头轮组_矿用刮板_厢式刮板机_铸石刮板机厂家-双驰机械 | 行星搅拌机,双行星搅拌机,动力混合机,无锡米克斯行星搅拌机生产厂家 | 定量包装秤,吨袋包装称,伸缩溜管,全自动包装秤,码垛机器人,无锡市邦尧机械工程有限公司 | 同学聚会纪念册制作_毕业相册制作-成都顺时针宣传画册设计公司 | 英语词典_成语词典_日语词典_法语词典_在线词典网 | 据信,上课带着跳 D 体验-别样的课堂刺激感受引发网友热议 | 海南在线 海南一家| PVC地板|PVC塑胶地板|PVC地板厂家|地板胶|防静电地板-无锡腾方装饰材料有限公司-咨询热线:4008-798-128 | 石膏基自流平砂浆厂家-高强石膏基保温隔声自流平-轻质抹灰石膏粉砂浆批发-永康市汇利建设有限公司 | 耐酸泵,耐腐蚀真空泵,耐酸真空泵-淄博华舜耐腐蚀真空泵有限公司 精密模具-双色注塑模具加工-深圳铭洋宇通 | 气力输送_输送机械_自动化配料系统_负压吸送_制造主力军江苏高达智能装备有限公司! | 上海物流公司,上海货运公司,上海物流专线-优骐物流公司 | Magnescale探规,Magnescale磁栅尺,Magnescale传感器,Magnescale测厚仪,Mitutoyo光栅尺,笔式位移传感器-苏州连达精密量仪有限公司 | 屏蔽服(500kv-超高压-特高压-电磁)-徐吉电气 | 比亚迪叉车-比亚迪电动叉车堆垛车托盘车仓储叉车价格多少钱报价 磁力去毛刺机_去毛刺磁力抛光机_磁力光饰机_磁力滚抛机_精密金属零件去毛刺机厂家-冠古科技 | 天津蒸汽/热水锅炉-电锅炉安装维修直销厂家-天津鑫淼暖通设备有限公司 | 上海噪音治理公司-专业隔音降噪公司-中广通环保 | 房间温控器|LonWorks|海思 | 展厅设计-展馆设计-专业企业展厅展馆设计公司-昆明华文创意 | 郑州宣传片拍摄-TVC广告片拍摄-微电影短视频制作-河南优柿文化传媒有限公司 | 上海皓越真空设备有限公司官网-真空炉-真空热压烧结炉-sps放电等离子烧结炉 | 暴风影音| CXB船用变压器-JCZ系列制动器-HH101船用铜质开关-上海永上船舶电器厂 | 伊卡洛斯软装首页-电动窗帘,别墅窗帘,定制窗帘,江浙沪1000+别墅窗帘案例 | 行吊_电动单梁起重机_双梁起重机_合肥起重机_厂家_合肥市神雕起重机械有限公司 | 制氮设备_PSA制氮机_激光切割制氮机_氮气机生产厂家-苏州西斯气体设备有限公司 | 游泳池设备安装工程_恒温泳池设备_儿童游泳池设备厂家_游泳池水处理设备-东莞市君达泳池设备有限公司 | 热处理温控箱,热处理控制箱厂家-吴江市兴达电热设备厂 | 深圳激光打标机_激光打标机_激光焊接机_激光切割机_同体激光打标机-深圳市创想激光科技有限公司 深圳快餐店设计-餐饮设计公司-餐饮空间品牌全案设计-深圳市勤蜂装饰工程 |