CyclicBarrier:循环栅栏

CyclicBarrier是另一种多线程并发的是工具,和CountDownLatch非常类似,它也可以实现线程间的计数等待,它的功能比CountDownLatch更加强大。因为CyclicBarrier是循环栅栏,所有的线程必须在栅栏处等待,并且可以循环使用。假设我们将计数器设置为10,那么凑齐第一个10个线程后,计数其就会归0,并重新计算。

比如我们要求十个线程一起去执行任务;这时我们需要先让这10个线程集合,接着,一起去执行任务,当这10个线程吧任务都执行完了,那么才算任务全部执行完毕!

CycliBarrier比CountDownLatch稍微强大点,CycliBarrier可以接收一个参数作为barrierAction,所谓barrierAction就是当计数器一次计数完成后,系统会执行的动作,如下构造函数中,parties表示计数总数,也就是参与的线程总数。

public CyclicBarrier(int perties, Runnable barrierAction);

示例代码如下所示:

package cn.yan.current;

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class TestCyclicBarrier {

    public static class Task implements Runnable {
        private String taskName;
        private final CyclicBarrier cyclicBarrier;

        public Task(String taskName, CyclicBarrier cyclicBarrier) {
            this.taskName = taskName;
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            try {
                // 等待所有任务到齐
                cyclicBarrier.await();
                doTask();
                // 等待所有任务执行完毕
                cyclicBarrier.await();
            } catch (InterruptedException | BrokenBarrierException ex) {
                ex.printStackTrace();
            }
        }

        void doTask() {
            try {
                Thread.sleep(Math.abs(new Random().nextInt() % 10000));
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            System.out.println("task over!");
        }
    }

    public static class BarrierAction implements Runnable {
        private boolean flag;
        private int n;

        public BarrierAction(boolean flag, int n) {
            this.flag = flag;
            this.n = n;
        }

        @Override
        public void run() {
            if (flag) {
                System.out.println("第" + n + "个,任务完成!");
            } else {
                System.out.println("task" + n + "个,集合完毕!");
                flag = true;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        final int n = 10;
        Thread[] allTasks = new Thread[10];
        boolean flag = false;

        CyclicBarrier cyclicBarrier = new CyclicBarrier(n, new BarrierAction(flag, n));
        // 设置屏障点
        System.out.println("任务集合");
        for (int i = 0; i < n; i++) {
            System.out.println("第" + i + "任务准备执行。");
            allTasks[i] = new Thread(new Task("任务" + i, cyclicBarrier));
            allTasks[i].start();
        }
    }
}

其执行结果如下:

/usr/jdk-9.0.1/bin/java -javaagent:/home/shuai/software/idea-IU-173.3727.127/lib/idea_rt.jar=42317:/home/shuai/software/idea-IU-173.3727.127/bin -Dfile.encoding=UTF-8 -classpath /home/shuai/IdeaProjects/cn-netty/out/production/classes cn.yan.current.TestCyclicBarrier
任务集合
第0任务准备执行。
第1任务准备执行。
第2任务准备执行。
第3任务准备执行。
第4任务准备执行。
第5任务准备执行。
第6任务准备执行。
第7任务准备执行。
第8任务准备执行。
第9任务准备执行。
task10个,集合完毕!
task over!
task over!
task over!
task over!
task over!
task over!
task over!
task over!
task over!
task over!
第10个,任务完成!

Process finished with exit code 0

 

上一篇:CyclicBarrier 源码分析


下一篇:并发编程及工具类