CountDownLatch和CyclicBarrier到底有什么区别

Bertha 。 2023-03-02 04:53 118阅读 0赞

CountDownLatch和CyclicBarrier在进行多线程编程时会见到,通常CountDownLatch在业务中会用的多点,我们先来看下CountDownLatch和CyclicBarrier的2个小例子:

  • CountDownLatch 测试代码

    public class CountDownLatchTest {

    1. static ExecutorService pool = Executors.newFixedThreadPool(3);
    2. public static void main(String[] args) {
    3. countDownLatch();
    4. }
    5. static void countDownLatch() {
    6. long t1 = System.currentTimeMillis();
    7. int count = 3;
    8. CountDownLatch latch = new CountDownLatch(count);
    9. for (int i = 1; i <= count; i++) {
    10. int finalI = i;
    11. pool.execute(new Runnable() {
    12. @Override
    13. public void run() {
    14. System.out.println(finalI + ":run");
    15. try {
    16. Thread.sleep(1000);
    17. } catch (InterruptedException e) {
    18. e.printStackTrace();
    19. } finally {
    20. latch.countDown();
    21. }
    22. }
    23. });
    24. }
    25. try {
    26. latch.await();
    27. } catch (InterruptedException e) {
    28. e.printStackTrace();
    29. }
    30. long t2 = System.currentTimeMillis();
    31. System.out.println("耗时:" + (t2 - t1) + "ms");
    32. System.out.println("main");
    33. }

    }

  • CountDownLatch测试的运行结果:

20200911111959780.png

从上图的运行结果中可以看到CountDownLatch主要的作用是等待子线程执行完成后,主线程再继续往下走.

  • CyclicBarrier测试代码

    public class CyclicBarrierTest {

    1. static ExecutorService pool = Executors.newFixedThreadPool(10);
    2. public static void main(String[] args) {
    3. cyclicBarrier();
    4. }
    5. static void cyclicBarrier() {
    6. long t1 = System.currentTimeMillis();
    7. int count = 3;
    8. CyclicBarrier barrier = new CyclicBarrier(count, () -> {
    9. long t2 = System.currentTimeMillis();
    10. System.out.println("耗时:" + (t2 - t1) + "ms");
    11. });
    12. for (int i = 1; i <= count; i++) {
    13. int finalI = i;
    14. pool.execute(new Runnable() {
    15. @Override
    16. public void run() {
    17. try {
    18. System.out.println(finalI + ":run");
    19. Thread.sleep(1000);
    20. barrier.await();
    21. } catch (Exception e) {
    22. e.printStackTrace();
    23. }
    24. }
    25. });
    26. }
    27. System.out.println("main");
    28. }

    }

  • CyclicBarrier测试的运行结果

20200911115338434.png

20200911134013683.png

从上图中可以看到,虽然主线程执行的顺序不一样,但是耗时一定是最后执行的。

通过上面的2个小例子,我们可以知道假设有一个接口需要知道多线程任务执行完成花了多长时间,直接使用CyclicBarrier就可以异步打印出多线程任务的耗时时间。

以前总觉得CountDownLatch和CyclicBarrier没什么区别,都是等子线程执行完了之后再执行后续的逻辑。但是区别就是CountDownLatch后续的逻辑只能由主线程完成,而CyclicBarrier后续的逻辑是由子线程完成的。也就是说CountDownLatch在做子线程运行完成之后的任务时,必须是同步完成的;而CyclicBarrier是可以异步完成的。

总结:

总的来说,CyclicBarrier相对于CountDownLatch就是可以异步处理多线程任务的运行结果,比如多线程的耗时时间、线程任务的运行结果的汇总和统计,以及数据合并等都可以使用CyclicBarrier。

发表评论

表情:
评论列表 (有 0 条评论,118人围观)

还没有评论,来说两句吧...

相关阅读