CyclicBarrier可以控制这样的场景:
对多个线程,他们执行自己代码(运行run方法)的时间不一样;
比如有3个线程,其run方法执行时间分别为1s, 2s, 3s。如果我们想在三个线程都完成自己的任务时执行相应的操作,CyclicBarrier就派上用场了。
写了一个简单的测试类,方便理解:
package cn.demo;import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;public class CyclicBarrierTest {private static int workerCount = 3; // 3个工人private static CyclicBarrier barrier;// Worker类, 其中的run方法表示在做任务static class Worker implements Runnable {@Overridepublic void run() {try {Thread.sleep(new Random().nextInt(1000)); // 工人(当前线程)做完自己的任务经历的时间System.out.println(Thread.currentThread().getName() + "做完了任务, 到达barrier,等待其他人。");barrier.await(); // 工人(当前线程)在barrier前等待其他工人做完任务System.out.println(Thread.currentThread().getName() + "继续做自己的事情");} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}}public static void main(String[] args) {
// barrier = new CyclicBarrier(workerCount);// new CyclicBarrier(int parties, Runnable barrierAction)// 表示第parties个(也就是最后一个)线程到达barrier时,触发barrierAction(也就是里边的run方法)barrier = new CyclicBarrier(workerCount, new Runnable() {@Overridepublic void run() {System.out.println("最后一个完成任务的人:" + Thread.currentThread().getName());}});for (int i = 0; i < workerCount; i++) {new Thread(new Worker()).start();}}
}
可能的输出结果:
Thread-1做完了任务, 到达barrier,等待其他人。
Thread-2做完了任务, 到达barrier,等待其他人。
Thread-0做完了任务, 到达barrier,等待其他人。
最后一个完成任务的人:Thread-0
Thread-0继续做自己的事情
Thread-1继续做自己的事情
Thread-2继续做自己的事情
可以用图表示为:
时间:------------------------------------>
--------------------barrier---------------|
T0 |
T1 |
T2 ||T1| // 线程1先到,等待其他线程T2 |T0 ||T1| // 线程2也到了,由于3个人没齐,线程1和2都在等T2|T0 ||T1 // 3个人都到了,放开屏障(barrier)T2T0
参考:
https://www.cnblogs.com/skywang12345/p/3533995.html
欢迎补充指正!