Java 并发编程 - CyclicBarrier

J.U.C 之 AQS - CyclicBarrier

  • 1、关于 CyclicBarrier
  • 2、await 方法
    • 2.1 不带参的 await 方法
    • 2.2 带参的 await 方法
    • 2.3 CyclicBarrier 带 Runnable 参数构造
  • 3、CyclicBarrier 与 CountDownLatch 的区别

1、关于 CyclicBarrier

 

CyclicBarrier : 它的作用就是会让所有线程都等待完成后才会继续下一步行动。

Java 并发编程 - CyclicBarrier_第1张图片
Java 并发编程 - CyclicBarrier_第2张图片
 
使用场景:

       一个线程组的线程,需要等待所有线程完成任务后,再继续执行下一次任务。可以用于多线程计算数据,最后合并计算结果的场景。

 
构造方法:

  • public CyclicBarrier(int parties);

    让 parties 个线程都等待完成后才会继续下一步行动.

  • public CyclicBarrier(int parties, Runnable barrierAction);

    parties 参数是参与线程的个数. Runnable 参数的意思是最后一个到达线程要做的任务.

    用于线程到达屏障时,优先执行barrierAction,方便处理更复杂的业务场景。

 

2、await 方法

 

2.1 不带参的 await 方法

 
await() : 调用await方法的线程告诉CyclicBarrier自己已经到达同步点,然后当前线程被阻塞。直到parties个参与线程调用了await方法,才会释放阻塞,继续进行各线程业务逻辑。
 

代码示例:

package com.lcao.aqs;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author
 * @title: CyclicBarrierExample
 * @description: TODO
 * @date 2020/4/21 15:23
 */
@Slf4j
public class CyclicBarrierExample {


    private static Integer threadCount = 20;

    private static  CyclicBarrier cyclicBarrier = new CyclicBarrier(5);

    public static void main(String[] args) throws Exception{

        ExecutorService threadPool = Executors.newCachedThreadPool();

        for (int i = 1;i<= threadCount; i++ ) {
        
            final int num = i;
            
            Thread.sleep(1000); // 这里为了让控制台打印更直观,让线程休眠一秒
            
            threadPool.execute(() -> {
            
                try {
                    testMethod(num);
                } catch (Exception e) {
                    log.info("{}-线程执行异常!", num);
                }
                
            });

        }
        threadPool.shutdown();
    }

    public static void testMethod (int num) throws Exception {
    
	      Thread.sleep(1000);  // 线程休眠一秒
	      
	      log.info("{}-准备就绪,等待执行!", num);
	      
	      cyclicBarrier.await();
	      
	      log.info("{}-执行成功!", num);
    }

}

 
执行结果:


15:56:58.422 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample - 1-准备就绪,等待执行!
15:56:59.420 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample - 2-准备就绪,等待执行!
15:57:00.420 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample - 3-准备就绪,等待执行!
15:57:01.420 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample - 4-准备就绪,等待执行!
15:57:02.421 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample - 5-准备就绪,等待执行!
15:57:02.421 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample - 1-执行成功!
15:57:02.421 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample - 4-执行成功!
15:57:02.421 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample - 3-执行成功!
15:57:02.421 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample - 2-执行成功!
15:57:02.421 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample - 5-执行成功!
15:57:03.421 [pool-1-thread-6] INFO com.lcao.aqs.CyclicBarrierExample - 6-准备就绪,等待执行!
15:57:04.422 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample - 7-准备就绪,等待执行!
15:57:05.422 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample - 8-准备就绪,等待执行!
15:57:06.423 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample - 9-准备就绪,等待执行!
15:57:07.423 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample - 10-准备就绪,等待执行!
15:57:07.423 [pool-1-thread-6] INFO com.lcao.aqs.CyclicBarrierExample - 6-执行成功!
15:57:07.423 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample - 7-执行成功!
15:57:07.423 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample - 8-执行成功!
15:57:07.423 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample - 9-执行成功!
15:57:07.423 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample - 10-执行成功!
15:57:08.424 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample - 11-准备就绪,等待执行!
15:57:09.425 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample - 12-准备就绪,等待执行!
15:57:10.426 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample - 13-准备就绪,等待执行!
15:57:11.426 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample - 14-准备就绪,等待执行!
15:57:12.427 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample - 15-准备就绪,等待执行!
15:57:12.427 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample - 15-执行成功!
15:57:12.427 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample - 11-执行成功!
15:57:12.427 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample - 12-执行成功!
15:57:12.427 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample - 13-执行成功!
15:57:12.427 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample - 14-执行成功!
15:57:13.428 [pool-1-thread-6] INFO com.lcao.aqs.CyclicBarrierExample - 16-准备就绪,等待执行!
15:57:14.428 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample - 17-准备就绪,等待执行!
15:57:15.429 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample - 18-准备就绪,等待执行!
15:57:16.430 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample - 19-准备就绪,等待执行!
15:57:17.430 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample - 20-准备就绪,等待执行!
15:57:17.430 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample - 20-执行成功!
15:57:17.430 [pool-1-thread-6] INFO com.lcao.aqs.CyclicBarrierExample - 16-执行成功!
15:57:17.430 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample - 17-执行成功!
15:57:17.430 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample - 18-执行成功!
15:57:17.430 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample - 19-执行成功!

Process finished with exit code 0

 

2.2 带参的 await 方法

 
await(long timeout, TimeUnit unit)带参方法,第一个参数是超时时间,第二个参数是超时时间单位。
 
使用该方法表示,如果等待时间到达了超时时间,那么已经达到同步点的线程释放阻塞,继续进行相关线程业务逻辑。
 
代码示例:

package com.lcao.aqs;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * @author
 * @title: CyclicBarrierExample
 * @description: TODO
 * @date 2020/4/21 15:23
 */
@Slf4j
public class CyclicBarrierExample2 {


    private static Integer threadCount = 10;

    private static  CyclicBarrier cyclicBarrier = new CyclicBarrier(5);

    public static void main(String[] args) throws Exception{

        ExecutorService threadPool = Executors.newCachedThreadPool();

        for (int i = 1;i<= threadCount; i++ ) {
            final int num = i;
            Thread.sleep(1000); // 这里为了让控制台打印更直观,让线程休眠一秒
            threadPool.execute(() -> {
                try {
                    testMethod(num);
                } catch (Exception e) {
                    log.info("{}-线程执行异常!", num);
                }
            });

        }
        threadPool.shutdown();
    }

    public static void testMethod (int num) throws Exception {
    
      Thread.sleep(1000);  // 线程休眠一秒
      
      log.info("{}-准备就绪,等待执行!", num);
      
      // 这里使用  await(long timeout, TimeUnit unit) 方法
      // 该方法的含义是,当等待时间达到超时时间后,便不再等待,直接执行。
      // 这里会抛出异常,所以在使用await带参方法时,一定要对异常进行捕获处理,以便不影响后续逻辑
      try {
          cyclicBarrier.await(1000, TimeUnit.MILLISECONDS);
      } catch (TimeoutException | BrokenBarrierException e) {
          log.warn("BarrierExceptions", e);
      }

      log.info("{}-执行成功!", num);
    }

}

 
执行结果:


15:58:38.136 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample2 - 1-准备就绪,等待执行!
15:58:39.136 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample2 - 2-准备就绪,等待执行!
15:58:39.142 [pool-1-thread-2] WARN com.lcao.aqs.CyclicBarrierExample2 - BarrierExceptions
java.util.concurrent.BrokenBarrierException: null
	at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:250)
	at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:435)
	at com.lcao.aqs.CyclicBarrierExample2.testMethod(CyclicBarrierExample2.java:47)
	at com.lcao.aqs.CyclicBarrierExample2.lambda$main$0(CyclicBarrierExample2.java:30)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
15:58:39.142 [pool-1-thread-1] WARN com.lcao.aqs.CyclicBarrierExample2 - BarrierExceptions
java.util.concurrent.TimeoutException: null
	at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:257)
	at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:435)
	at com.lcao.aqs.CyclicBarrierExample2.testMethod(CyclicBarrierExample2.java:47)
	at com.lcao.aqs.CyclicBarrierExample2.lambda$main$0(CyclicBarrierExample2.java:30)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
15:58:39.143 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample2 - 2-执行成功!
15:58:39.143 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample2 - 1-执行成功!
15:58:40.136 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample2 - 3-准备就绪,等待执行!
15:58:40.136 [pool-1-thread-3] WARN com.lcao.aqs.CyclicBarrierExample2 - BarrierExceptions
java.util.concurrent.BrokenBarrierException: null
	at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207)
	at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:435)
	at com.lcao.aqs.CyclicBarrierExample2.testMethod(CyclicBarrierExample2.java:47)
	at com.lcao.aqs.CyclicBarrierExample2.lambda$main$0(CyclicBarrierExample2.java:30)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
15:58:40.136 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample2 - 3-执行成功!
15:58:41.136 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample2 - 4-准备就绪,等待执行!
15:58:41.136 [pool-1-thread-1] WARN com.lcao.aqs.CyclicBarrierExample2 - BarrierExceptions
java.util.concurrent.BrokenBarrierException: null
	at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207)
	at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:435)
	at com.lcao.aqs.CyclicBarrierExample2.testMethod(CyclicBarrierExample2.java:47)
	at com.lcao.aqs.CyclicBarrierExample2.lambda$main$0(CyclicBarrierExample2.java:30)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
15:58:41.136 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample2 - 4-执行成功!
15:58:42.137 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample2 - 5-准备就绪,等待执行!
15:58:42.137 [pool-1-thread-3] WARN com.lcao.aqs.CyclicBarrierExample2 - BarrierExceptions
java.util.concurrent.BrokenBarrierException: null
	at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207)
	at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:435)
	at com.lcao.aqs.CyclicBarrierExample2.testMethod(CyclicBarrierExample2.java:47)
	at com.lcao.aqs.CyclicBarrierExample2.lambda$main$0(CyclicBarrierExample2.java:30)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
15:58:42.137 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample2 - 5-执行成功!
15:58:43.137 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample2 - 6-准备就绪,等待执行!
15:58:43.137 [pool-1-thread-1] WARN com.lcao.aqs.CyclicBarrierExample2 - BarrierExceptions
java.util.concurrent.BrokenBarrierException: null
	at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207)
	at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:435)
	at com.lcao.aqs.CyclicBarrierExample2.testMethod(CyclicBarrierExample2.java:47)
	at com.lcao.aqs.CyclicBarrierExample2.lambda$main$0(CyclicBarrierExample2.java:30)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
15:58:43.137 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample2 - 6-执行成功!
15:58:44.137 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample2 - 7-准备就绪,等待执行!
15:58:44.137 [pool-1-thread-3] WARN com.lcao.aqs.CyclicBarrierExample2 - BarrierExceptions
java.util.concurrent.BrokenBarrierException: null
	at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207)
	at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:435)
	at com.lcao.aqs.CyclicBarrierExample2.testMethod(CyclicBarrierExample2.java:47)
	at com.lcao.aqs.CyclicBarrierExample2.lambda$main$0(CyclicBarrierExample2.java:30)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
15:58:44.137 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample2 - 7-执行成功!
15:58:45.137 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample2 - 8-准备就绪,等待执行!
15:58:45.137 [pool-1-thread-1] WARN com.lcao.aqs.CyclicBarrierExample2 - BarrierExceptions
java.util.concurrent.BrokenBarrierException: null
	at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207)
	at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:435)
	at com.lcao.aqs.CyclicBarrierExample2.testMethod(CyclicBarrierExample2.java:47)
	at com.lcao.aqs.CyclicBarrierExample2.lambda$main$0(CyclicBarrierExample2.java:30)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
15:58:45.137 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample2 - 8-执行成功!
15:58:46.137 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample2 - 9-准备就绪,等待执行!
15:58:46.137 [pool-1-thread-3] WARN com.lcao.aqs.CyclicBarrierExample2 - BarrierExceptions
java.util.concurrent.BrokenBarrierException: null
	at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207)
	at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:435)
	at com.lcao.aqs.CyclicBarrierExample2.testMethod(CyclicBarrierExample2.java:47)
	at com.lcao.aqs.CyclicBarrierExample2.lambda$main$0(CyclicBarrierExample2.java:30)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
15:58:46.137 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample2 - 9-执行成功!
15:58:47.138 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample2 - 10-准备就绪,等待执行!
15:58:47.138 [pool-1-thread-1] WARN com.lcao.aqs.CyclicBarrierExample2 - BarrierExceptions
java.util.concurrent.BrokenBarrierException: null
	at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:207)
	at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:435)
	at com.lcao.aqs.CyclicBarrierExample2.testMethod(CyclicBarrierExample2.java:47)
	at com.lcao.aqs.CyclicBarrierExample2.lambda$main$0(CyclicBarrierExample2.java:30)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
15:58:47.138 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample2 - 10-执行成功!

Process finished with exit code 0

 

2.3 CyclicBarrier 带 Runnable 参数构造

 

这是 CyclicBarrier 类中含 Runnable 参数的源码,其中 Runnable 类中的业务逻辑,在 parties个线程都准备好之后执行。

public CyclicBarrier(int parties, Runnable barrierAction) {
        if (parties <= 0) throw new IllegalArgumentException();
        this.parties = parties;
        this.count = parties;
        this.barrierCommand = barrierAction;
    }

 
代码示例:

package com.lcao.aqs;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author
 * @title: CyclicBarrierExample1
 * @description: TODO
 * @date 2020/4/21 15:37
 */
@Slf4j
public class CyclicBarrierExample1 {

    private static Integer threadCount = 20;

    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5,() ->{
        log.info("所有线程准备完成后,到达这一步,然后再执行各线程逻辑");
    });

    public static void main(String[] args) throws Exception{

        ExecutorService threadPool = Executors.newCachedThreadPool();

        for (int i = 1;i<= threadCount; i++ ) {
            final int num = i;
            Thread.sleep(1000); // 这里为了让控制台打印更直观,让线程休眠一秒
            threadPool.execute(() -> {
                try {
                    testMethod(num);
                } catch (Exception e) {
                    log.info("{}-线程执行异常!", num);
                }
            });

        }
        threadPool.shutdown();
    }

    public static void testMethod (int num) throws Exception {
        Thread.sleep(1000);  // 线程休眠一秒
        log.info("{}-准备就绪,等待执行!", num);
        cyclicBarrier.await();
        log.info("{}-执行成功!", num);
    }

}

 
执行结果:


15:59:43.938 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample1 - 1-准备就绪,等待执行!
15:59:44.935 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample1 - 2-准备就绪,等待执行!
15:59:45.937 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample1 - 3-准备就绪,等待执行!
15:59:46.936 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample1 - 4-准备就绪,等待执行!
15:59:47.937 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample1 - 5-准备就绪,等待执行!
15:59:47.937 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample1 - 所有线程准备完成后,到达这一步,然后再执行各线程逻辑
15:59:47.938 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample1 - 1-执行成功!
15:59:47.938 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample1 - 2-执行成功!
15:59:47.938 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample1 - 3-执行成功!
15:59:47.938 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample1 - 4-执行成功!
15:59:47.938 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample1 - 5-执行成功!
15:59:48.938 [pool-1-thread-6] INFO com.lcao.aqs.CyclicBarrierExample1 - 6-准备就绪,等待执行!
15:59:49.937 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample1 - 7-准备就绪,等待执行!
15:59:50.938 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample1 - 8-准备就绪,等待执行!
15:59:51.939 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample1 - 9-准备就绪,等待执行!
15:59:52.939 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample1 - 10-准备就绪,等待执行!
15:59:52.939 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample1 - 所有线程准备完成后,到达这一步,然后再执行各线程逻辑
15:59:52.939 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample1 - 7-执行成功!
15:59:52.939 [pool-1-thread-6] INFO com.lcao.aqs.CyclicBarrierExample1 - 6-执行成功!
15:59:52.939 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample1 - 8-执行成功!
15:59:52.939 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample1 - 9-执行成功!
15:59:52.939 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample1 - 10-执行成功!
15:59:53.940 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample1 - 11-准备就绪,等待执行!
15:59:54.940 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample1 - 12-准备就绪,等待执行!
15:59:55.940 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample1 - 13-准备就绪,等待执行!
15:59:56.941 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample1 - 14-准备就绪,等待执行!
15:59:57.942 [pool-1-thread-6] INFO com.lcao.aqs.CyclicBarrierExample1 - 15-准备就绪,等待执行!
15:59:57.942 [pool-1-thread-6] INFO com.lcao.aqs.CyclicBarrierExample1 - 所有线程准备完成后,到达这一步,然后再执行各线程逻辑
15:59:57.942 [pool-1-thread-6] INFO com.lcao.aqs.CyclicBarrierExample1 - 15-执行成功!
15:59:57.942 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample1 - 11-执行成功!
15:59:57.942 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample1 - 12-执行成功!
15:59:57.942 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample1 - 13-执行成功!
15:59:57.942 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample1 - 14-执行成功!
15:59:58.942 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample1 - 16-准备就绪,等待执行!
15:59:59.942 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample1 - 17-准备就绪,等待执行!
16:00:00.943 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample1 - 18-准备就绪,等待执行!
16:00:01.943 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample1 - 19-准备就绪,等待执行!
16:00:02.944 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample1 - 20-准备就绪,等待执行!
16:00:02.944 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample1 - 所有线程准备完成后,到达这一步,然后再执行各线程逻辑
16:00:02.944 [pool-1-thread-2] INFO com.lcao.aqs.CyclicBarrierExample1 - 20-执行成功!
16:00:02.944 [pool-1-thread-1] INFO com.lcao.aqs.CyclicBarrierExample1 - 17-执行成功!
16:00:02.944 [pool-1-thread-4] INFO com.lcao.aqs.CyclicBarrierExample1 - 18-执行成功!
16:00:02.944 [pool-1-thread-5] INFO com.lcao.aqs.CyclicBarrierExample1 - 16-执行成功!
16:00:02.944 [pool-1-thread-3] INFO com.lcao.aqs.CyclicBarrierExample1 - 19-执行成功!

Process finished with exit code 0

 

补充说明 :


//上述示例中代码:

private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5,() ->{
        log.info("所有线程准备完成后,到达这一步,然后再执行各线程逻辑");
    });
  
// 等同于:

private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
        @Override
        public void run() {
            log.info("所有线程准备完成后,到达这一步,然后再执行各线程逻辑");
        }
    });  
    

 

3、CyclicBarrier 与 CountDownLatch 的区别

 

  • CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的,所以CyclicBarrier能够处理更为复杂的场景。
     
  • CyclicBarrier还提供了一些其他有用的方法,比如getNumberWaiting()方法可以获得CyclicBarrier阻塞的线程数量,isBroken()方法用来了解阻塞的线程是否被中断。
     
  • CountDownLatch允许一个或多个线程等待一组事件的产生,而CyclicBarrier用于等待其他线程运行到栅栏位置。

 
 
 
 
 
 
 
 
 
 
 
 
 
 
.

你可能感兴趣的:(线程系列,多线程,并发编程,CyclicBarrier,await,thread)