CyclicBarrier
循环栅栏,用来进行线程协作,等待线程满足某个计数,构造时设置[计数个数],每个线程执行到某个需要同步的时刻调用await()方法进行等待,当等待的线程数满足【计数个数】时,继续执行
与CountDownLatch区别是可以重复使用
CyclicBarrier的计数变为0之后,再次调用await方法计数会重新变为设置值,想要重复执行任务并等待只需要创建一个对象
将任务反复运行,并且主线程将返回得到的数据进行汇总:
public static void main(String[] args) {ExecutorService service = Executors.newFixedThreadPool(3);CyclicBarrier barrier = new CyclicBarrier(2, () -> {log.debug("task1, task2 finish...");});for (int i = 0; i < 3; i++) { // task1 task2 task1service.submit(() -> {log.debug("task1 begin...");sleep(1);try {barrier.await(); // 2-1=1} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}});service.submit(() -> {log.debug("task2 begin...");sleep(2);try {barrier.await(); // 1-1=0} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}});}service.shutdown();}
CountDownLatch也可以达到上述效果
private static void test1() {ExecutorService service = Executors.newFixedThreadPool(5);for (int i = 0; i < 3; i++) {CountDownLatch latch = new CountDownLatch(2);service.submit(() -> {log.debug("task1 start...");sleep(1);latch.countDown();});service.submit(() -> {log.debug("task2 start...");sleep(2);latch.countDown();});try {latch.await();} catch (InterruptedException e) {e.printStackTrace();}log.debug("task1 task2 finish...");}service.shutdown();}
CyclicBarrier注意点:
线程池中的线程数要与计数值一致,否则会有问题
如上述代码,任务1执行1s,任务2执行2s,若线程数有三个,而计数是2,则导致三个线程直接去执行两个任务1,一个任务2,当任务1时间短先执行完,返回的结果均为任务1的,而不会得到任务2的结果
