Java CyclicBarrier使用

 使用说明
栅栏类似于闭锁,它能阻塞一组线程直到某个事件的发生。栅栏与闭锁的关键区别在于,所有的线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待事件,而栅栏用于等待其他线程。
CyclicBarrier可以使一定数量的线程反复地在栅栏位置处汇集。当线程到达栅栏位置时将调用await方法,这个方法将阻塞直到指定数量的线程都到达栅栏位置。如果所有线程都到达栅栏位置,那么栅栏将打开,此时所有的线程都将被释放,而栅栏将被重置以便下次使用。


 构造器
 CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程使用await()方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。

 CyclicBarrier的另一个构造函数CyclicBarrier(int parties, Runnable barrierAction),用于线程到达屏障时,优先执行barrierAction,方便处理更复杂的业务场景。

 核心方法:
 public int await() throws InterruptedException, BrokenBarrierException
    阻塞直到指定数量的线程到达栅栏位置

 public int await(long timeout, TimeUnit unit) throws InterruptedException,BrokenBarrierException,TimeoutException
        阻塞直到指定数量的线程到达栅栏位置或到达了指定最长时间

Demo

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

        Soldier(CyclicBarrier cyclic,String soldierName){
            this.cyclic = cyclic;
            this.soldier = soldierName;
        }
        @Override
        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.flag = flag;
            this.N = N;
        }

        @Override
        public void run() {
            if (flag){
                System.out.println("司令:[士兵"+N+"个,任务完成!");
            }else{
                System.out.println("司令:[士兵"+N+"个,集合完毕!");
                flag = true;
            }
        }
    }


    public static void main(String[] args) {
        final int N = 10;
        Thread[] allSoldier = new Thread[N];
        CyclicBarrier  cyclicBarrier = new CyclicBarrier(N,new BarrierRun(false,N));

        //设置屏障点,主要是为了执行这个方法
        System.out.println("集合队伍!");

        for (int i = 0 ; i < N ; ++i){
            System.out.println("士兵"+i+"报道");
            allSoldier[i] = new Thread(new Soldier(cyclicBarrier,"士兵"+i));

            allSoldier[i].start();
        }
    }
}

结果:

集合队伍!
士兵0报道
士兵1报道
士兵2报道
士兵3报道
士兵4报道
士兵5报道
士兵6报道
士兵7报道
士兵8报道
士兵9报道
司令:[士兵10个,集合完毕!
士兵0:任务完成
士兵5:任务完成
士兵7:任务完成
士兵2:任务完成
士兵6:任务完成
士兵4:任务完成
士兵9:任务完成
士兵1:任务完成
士兵3:任务完成
士兵8:任务完成
司令:[士兵10个,任务完成!

你可能感兴趣的:(java多线程,CyclicBarrier)