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