循环栅栏:CyclicBarrier

发布时间:2023年12月21日

CyclicBarrier可以理解为循环栅栏,栅栏就是一种障碍物,
比如通常在私人宅院的周围就可以围上一圈栅栏,阻止闲杂人等入内。
这里当然就是用来阻止线程继续执行,要求线程在栅栏外等待。
前面的Cyclic意为循环,也就是说这个计数器可以反复使用。
比如,我们将计数器设置为10,那么凑齐第一批10个线程后,计数器就会归零,
接着凑齐下一批10个线程,这就是循环栅栏内在的含义。

CyclicBarrier的使用场景也很丰富。比如,司令下达命令,要求10个士兵一起去
完成一项任务。这时就会要求10个士兵集合报到,接着,一起雄赳赳,气昂昂地去执行任务。
当10个士兵把自己手上的任务都执行完成了,那么司令才对外宣布,任务完成。

CyclicBarrier比CountDownLatch稍微强大一些,
它可以接收一个参数作为barrierAction.
所谓barrierAction就是当计数器一次计数完成后,
系统会执行的动作。
其中parties表示计数总数,也就是参与的线程总数。

public class CyclicBarrierDemo {
    public static class Sodier implements Runnable{
        private String soldier;
        private final CyclicBarrier cyclic;

        Sodier(CyclicBarrier cyclic,String soldierName){
            this.cyclic = cyclic;
            this.soldier = soldierName;
        }
        public void run() {
            try{
                cyclic.await();
                doWork();
                cyclic.await();
            } catch (InterruptedException e){
                e.printStackTrace();
            } catch (BrokenBarrierException e){
                e.printStackTrace();
            }
        }
        void doWork(){
            try {
                Thread.sleep(Math.abs(new Random().nextInt()%10000));
            } catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println(soldier+":任务完成");
        }
    }
    public static class BarrierRun implements Runnable{
        boolean flag;
        int N;
        public BarrierRun(boolean flag,int N){
            this.N = N;
            this.flag = flag;
        }
        public void run() {
            if(flag){
                System.out.println("司令:[士兵"+ N +"个,任务完成!]");
            } else{
                System.out.println("司令:[士兵"+ N +"个,集合完毕!]");
                flag = true;
            }
        }
    }
    public static void main(String[] args) throws InterruptedException{
        final int N = 10;
        Thread[] allSoldier = new Thread[N];
        boolean flag = false;
        CyclicBarrier cyclic = new CyclicBarrier(N, new BarrierRun(flag,N));
        System.out.println("集合队伍!");
        for (int i =0;i< N; ++i){
            System.out.println("士兵"+i+"报道!");
            allSoldier[i] = new Thread(new Sodier(cyclic,"士兵"+i));
            allSoldier[i].start();
        }
    }
}

创建CyclicBarrier实例,并将计数器设置为10,要求在计数器到达指标时,
执行run()方法。每个士兵线程都会执行run方法。
在第18行cyclic.await()每个士兵都会等待,直到所有的士兵都集合完毕。
集合完毕意味着CyclicBarrier的一次计数完成,当再一次调用CyclicBarrier.await
方法时,会进行下一次计数。doWork();模拟了士兵的任务。
当一个士兵任务执行完,他就会要求CylicBarrier开始下一次计数,
这次计数主要目的是监控是否所有的士兵都已经完成了任务。
一旦任务全部完成。

文章来源:https://blog.csdn.net/wcg_jishuo/article/details/135118945
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。