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();
}
}
}