`

CountDownLatch和CyclicBarrier的区别

    博客分类:
  • java
阅读更多

在网上看到很多人对于CountDownLatch和CyclicBarrier的区别简单理解为CountDownLatch是一次性的,而 CyclicBarrier在调用reset之后还可以继续使用。那如果只是这么简单的话,我觉得CyclicBarrier简单命名为ResetableCountDownLatch好了,显然不是的。
我的理解是,要从他们的设计目的去看这两个类。javadoc里面的描述是这样的。

 

CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

CyclicBarrier : A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.

 

可能是我的英语不够好吧, 我感觉从这个javadoc里面要准确理解他们的差异还是不容易的。
我的理解是

 

CountDownLatch一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。   CyclicBarrier        : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。

 


 

CountDownLatch 是计数器, 线程完成一个就记一个, 就像 报数一样, 只不过是递减的.

 

而CyclicBarrier更像一个水闸, 线程执行就想水流, 在水闸处都会堵住, 等到水满(线程到齐)了, 才开始泄流.

 

 

 

CyclicBarrier

 

假设有只有的一个场景:每个线程代表一个跑步运动员,当运动员都准备好后,才一起出发,只要有一个人没有准备好,大家都等待.

 

    import java.io.IOException;  
    import java.util.Random;  
    import java.util.concurrent.BrokenBarrierException;  
    import java.util.concurrent.CyclicBarrier;  
    import java.util.concurrent.ExecutorService;  
    import java.util.concurrent.Executors;  
      
    class Runner implements Runnable {  
      
        private CyclicBarrier barrier;  
      
        private String name;  
      
        public Runner(CyclicBarrier barrier, String name) {  
            super();  
            this.barrier = barrier;  
            this.name = name;  
        }  
      
        @Override  
        public void run() {  
            try {  
                Thread.sleep(1000 * (new Random()).nextInt(8));  
                System.out.println(name + " 准备OK.");  
                barrier.await();  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            } catch (BrokenBarrierException e) {  
                e.printStackTrace();  
            }  
            System.out.println(name + " Go!!");  
        }  
    }  
      
    public class Race {  
      
        public static void main(String[] args) throws IOException, InterruptedException {  
            CyclicBarrier barrier = new CyclicBarrier(3);  
      
            ExecutorService executor = Executors.newFixedThreadPool(3);  
            executor.submit(new Thread(new Runner(barrier, "zhangsan")));  
            executor.submit(new Thread(new Runner(barrier, "lisi")));  
            executor.submit(new Thread(new Runner(barrier, "wangwu")));  
      
            executor.shutdown();  
        }  
      
    }  

 

总结:CyclicBarrier就是一个栅栏,等待所有线程到达后再执行相关的操作。barrier 在释放等待线程后可以重用。

 

 

 

CountDownLatch

 

 

    import java.util.concurrent.CountDownLatch;  
    /** 
     * 示例:CountDownLatch的使用举例 
     * Mail: ken@iamcoding.com 
     * @author janeky 
     */  
    public class TestCountDownLatch {  
        private static final int N = 10;  
      
        public static void main(String[] args) throws InterruptedException {  
            CountDownLatch doneSignal = new CountDownLatch(N);  
            CountDownLatch startSignal = new CountDownLatch(1);//开始执行信号  
      
            for (int i = 1; i <= N; i++) {  
                new Thread(new Worker(i, doneSignal, startSignal)).start();//线程启动了  
            }  
            System.out.println("begin------------");  
            startSignal.countDown();//开始执行啦  
            doneSignal.await();//等待所有的线程执行完毕  
            System.out.println("Ok");  
      
        }  
      
        static class Worker implements Runnable {  
            private final CountDownLatch doneSignal;  
            private final CountDownLatch startSignal;  
            private int beginIndex;  
      
            Worker(int beginIndex, CountDownLatch doneSignal,  
                    CountDownLatch startSignal) {  
                this.startSignal = startSignal;  
                this.beginIndex = beginIndex;  
                this.doneSignal = doneSignal;  
            }  
      
            public void run() {  
                try {  
                    startSignal.await(); //等待开始执行信号的发布  
                    beginIndex = (beginIndex - 1) * 10 + 1;  
                    for (int i = beginIndex; i <= beginIndex + 10; i++) {  
                        System.out.println(i);  
                    }  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                } finally {  
                    doneSignal.countDown();  
                }  
            }  
        }  
    }  

 

 

 


总结:CounDownLatch对于管理一组相关线程非常有用。上述示例代码中就形象地描述了两种使用情况。第一种是计算器为1,代表了两种状态,开 关。第二种是计数器为N,代表等待N个操作完成。今后我们在编写多线程程序时,可以使用这个构件来管理一组独立线程的执行。

 


作者: xumingming
网址: http://xumingming.sinaapp.com/215/countdownlatch-vs-cyclicbarrier/

分享到:
评论

相关推荐

    CountDownLatch和CyclicBarrier用法实例大全

    在Java并发编程中,CountDownLatch和CyclicBarrier是两种非常重要的同步工具类,它们用于协调多个线程间的协作。这两个工具都是在`java.util.concurrent`包下,是Java并发库的重要组成部分。 **CountDownLatch** ...

    Java中的CountDownLatch与CyclicBarrier:深入理解与应用实践

    在Java的并发编程中,CountDownLatch和CyclicBarrier是两个非常重要的同步工具,它们用于协调多个线程的执行顺序。本文将详细介绍CountDownLatch和CyclicBarrier的工作原理、使用场景以及如何在实际项目中应用它们。...

    java并发编程中CountDownLatch和CyclicBarrier的使用借鉴.pdf

    java并发编程中CountDownLatch和CyclicBarrier的使用借鉴 java并发编程中CountDownLatch和CyclicBarrier是两个非常重要的线程控制和调度工具,经常被用于解决多线程程序设计中的线程等待问题。本文将对...

    java并发编程中CountDownLatch和CyclicBarrier的使用.pdf

    总结一下,CountDownLatch和CyclicBarrier的主要区别在于: - **CountDownLatch** 是单次使用的,一旦计数器归零,就不能再复用。 - **CyclicBarrier** 可以重用,线程到达屏障点后,屏障会自动重置,允许线程再次...

    CountDownLatch 和 CyclicBarrier 的运用(含AQS详解)

    ### CountDownLatch 和 CyclicBarrier 的运用(含AQS详解) #### CountDownLatch **定义与特点:** CountDownLatch 是 Java 并发包中的一个重要组件,它主要用于解决“一个或多个线程等待其他线程完成任务”的问题。...

    详解java CountDownLatch和CyclicBarrier在内部实现和场景上的区别

    在Java并发编程中,CountDownLatch和CyclicBarrier都是用于协调多线程间同步的重要工具,它们可以帮助开发者在特定条件满足时启动或者结束线程的执行。本文将详细探讨这两个类的内部实现机制以及它们在实际应用场景...

    CountDownLatch、CyclicBarrier、Semaphore.md

    java 高并发应用场景

    Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解

    Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解 Java并发编程是Java语言中的一种高级技术,用于处理多线程编程中的同步问题。Java 1.5中引入了几个高效的辅助类,包括CountDownLatch、...

    Java并发编程一CountDownLatch、CyclicBarrier、Semaphore初使用

    在Java并发编程中,CountDownLatch、CyclicBarrier和Semaphore是三种重要的线程协作工具,它们都基于AbstractQueuedSynchronizer(AQS)框架来实现线程间的同步和协调。AQS是一个内置的锁和同步组件,它为构建高级...

    Java并发编程之美_部分71

    Java并发编程之美_部分71 本节主要讲解了Java并发包中线程同步器原理剖析,...本节主要讲解了 CountDownLatch 和 CyclicBarrier 的使用和原理剖析,了解了它们的使用场景和区别,可以更好地使用它们来实现线程同步。

    Java进阶教程,面试大全,包罗万象

    Java进阶教程,面试大全1,可参考以下问题: Semaphore-信号灯机制。 synchronized在静态方法和普通方法的区别。 怎么实现所有线程在等待某个事件的发生...CountDownLatch和CyclicBarrier的用法,以及相互之间的差别。

    Java进阶教程,面试大全

    Java进阶教程,面试大全1,可参考以下问题: Semaphore-信号灯机制。 synchronized在静态方法和普通方法的区别。 怎么实现所有线程在等待某个事件的发生...CountDownLatch和CyclicBarrier的用法,以及相互之间的差别。

    Java concurrency之CountDownLatch原理和示例_动力节点Java学院整理

    下面我们将深入探讨CountDownLatch的原理、使用方法以及与CyclicBarrier的区别。 首先,CountDownLatch的构造函数接受一个整数参数`count`,这个值表示计数器的初始值。当这个计数器归零时,所有等待在`await()`...

    蓝桥杯leetcode-JavaBase:Java一些类测试用例

    蓝桥杯leetcode 仓库内容是学习Java时所用的一些测试demo: 1. Cloneable ...CountDownLatch和CyclicBarrier区别 12. LanQiao 蓝桥杯的测试 13. LeetCode 在LeetCode刷的题 14. Test 一些偶尔的测试

    JUC面试知识点手册快速版

    4.1 CountDownLatch 4.2 CyclicBarrier 4.3 Semaphore 4.4 Exchanger 第五章:原子类和无锁编程 5.1 AtomicInteger与AtomicLong 5.2 AtomicReference 第六章:线程池及其应用 6.1 ThreadPoolExecutor 6.2...

    Java中的CountDownLatch类最全讲义

    目录: 简介 1.1 并发编程与线程同步 1.2 CountDownLatch概述 CountDownLatch的基本用法 2.1 创建CountDownLatch对象 2.2 await()方法 ...CountDownLatch与CyclicBarrier的对比 最佳实践与注意事项

    CountDownLatch练习

    1. **CountDownLatch与CyclicBarrier的区别**:CountDownLatch是一次性的,计数到零后无法重用;CyclicBarrier可以重置,允许多次同步点。 2. **如何避免死锁与饥饿**:在使用CountDownLatch时,要确保所有线程都能...

    Java线程核心技术及常见面试问题解答

    内容概要:本文详细介绍了Java线程的基本概念、线程的安全与同步机制、多种线程间通信方式、Java内存模型,以及线程池的原理与使用...和并发控制组件如synchronized、ReentrantLock、CountDownLatch、CyclicBarrier等...

    Java并发编程-3.pdf

    CountDownLatch、CyclicBarrier 和 Semaphore 等多线程协作机制都是 Java 并发编程中的重要组成部分。它们可以帮助开发者编写高效、可靠的多线程程序,解决复杂的并发问题。 在实际开发中,我们可以根据具体情况...

Global site tag (gtag.js) - Google Analytics