1.CyclicBarrier类说明
一个同步辅助类,字面意思是回环栅栏。它允许一组线程互相等待,直到到达某个公共屏障点。因为该类在释放线程后可重用,所以称为回环栅栏。
2.使用场景
当所有子任务都完成之后,再执行主任务。
3.具体代码及解析
package test;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CyclicBarrierTest extends Thread {
public static void main(String[] args) {
// 同步辅助类,允许一组线程互相等待,直到到达某个公共屏障点
CyclicBarrier barrier = new CyclicBarrier(5);
// 创建一个可重用固定线程数的线程池,超过这个最大线程数量,超出的线程不会运行
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(new Thread(new Runner(barrier, "张三")));
executor.submit(new Thread(new Runner(barrier, "李四")));
executor.submit(new Thread(new Runner(barrier, "王五")));
executor.submit(new Thread(new Runner(barrier, "刘六")));
executor.submit(new Thread(new Runner(barrier, "孙七")));
// 关闭ExecutorService,且终止前允许执行已经提交的任务
executor.shutdown();
// 关闭ExecutorService,阻止等待任务启动并试图停止正在运行的任务
// executor.shutdownNow();
}
}
class Runner implements Runnable {
private CyclicBarrier barrier;
private String name;
public Runner(CyclicBarrier barrier, String name) {
super();
this.barrier = barrier;
this.name = name;
}
@Override
public void run() {
try {
// 生成一个0-8之内的随机数
Thread.sleep(1000 * (new Random().nextInt(8)));
System.out.println(name + " 准备完毕!");
// 在所有线程都已经在此barrier上调用await方法之前,将一直等待
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(name + " 出发!");
}
}
4.结果展示及解析
由结果可以发现,当五个参赛者都准备完毕后,同时出发,实现了同时起跑的效果。
5.方法总结
1)// 关闭ExecutorService,不可以执行新的线程,已经执行的线程将继续执行。
executor.shutdown();
// 关闭ExecutorService,试图停止正在运行的任务,并返回尚未执行的线程。
executor.shutdownNow();
2)// 创建一个可重用固定线程数的线程池,超过这个最大线程数量,超出的线程不会运行
ExecutorService executor = Executors.newFixedThreadPool(5);
3)//创建一个0-8以内的随机数并转成int格式
new Random().nextInt(8)
4)// 在所有线程都已经在此barrier上调用await方法之前,将一直等待
barrier.await();
5)//如果()里的数字大于调用的线程数量,barrier将永远等待下去
CyclicBarrier barrier = new CyclicBarrier(5);