并发(二)CyclicBarrier

CyclicBarrier

循环屏障,用于一组固定数目的线程互相等待。使用场景如下:

主任务有一组串行的执行节点,每个节点之间有一批任务,固定数量的线程执行这些任务,执行完成后,在节点完成集合后,再继续执行下一批任务。

如下图所示:

 

屏障可以在每个节点处循环使用。构造屏障时,提供了一个可选的Runnable参数,每次执行完成后,会触发此Runnable。

    @Test
    public void test1() throws InterruptedException {
        final AtomicBoolean flag = new AtomicBoolean(false);

        CyclicBarrier barrier = new CyclicBarrier(5, new Runnable() {
            @Override
            public void run() {
                System.out.println("所有子任务运行完成!");
                flag.set(true);
            }
        });

        ExecutorService executorService = Executors.newCachedThreadPool();

        for(int i = 0; i < 5; i++) {
            executorService.execute(new Task(barrier));
        }

        while (!flag.get()) {
            Thread.sleep(100);
        }
        flag.set(false);

        for(int i = 0; i < 5; i++) {
            executorService.execute(new Task(barrier));
        }

        while (true) {
            Thread.sleep(1000);
        }
    }

    public static class Task implements Runnable {

        private CyclicBarrier barrier;

        public Task(CyclicBarrier barrier) {
            this.barrier = barrier;
        }

        @Override
        public void run() {
            try {
                Thread.sleep((long)(Math.random()*10000));
                System.err.println("now await nums=" + barrier.getNumberWaiting());
                barrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }

 

posted @ 2017-11-28 16:52  飞昂之雪  阅读(171)  评论(0编辑  收藏  举报