CountDownLatch和CyclicBarrier的区别

原创 2013年12月05日 16:08:59

在网上看到很多人对于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和Semaphore区别

下面对上面说的三个辅助类进行一个总结:   1)CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:     CountDownLatch一般用...

多线程CountDownLatch和CyclicBarrier的区别 以及举例

在网上看到很多人对于CountDownLatch和CyclicBarrier的区别简单理解为CountDownLatch是一次性的,而CyclicBarrier在调用reset之后还可以继续使用。那如...
  • paul342
  • paul342
  • 2015年11月05日 14:05
  • 543

CountDownLatch、CyclicBarrier、Semaphore共同之处与区别以及各自使用场景

摘要: jdk1.5之后,java的concurrent包提供了一些并发工具类,比如CountDownLatch和CyclicBarrier,Semaphore。这里简要的比较一下他们的共同之处与区别...

多线程之CountDownLatch和CyclicBarrier的区别和用法

一.CountDownLatch的使用 CountDownLatch经常用于监听某些初始化操作,等初始化执行完毕后,再通知主线程继续工作。 CountDownLatch定义: 一个同步辅助类,在完成...
  • a347911
  • a347911
  • 2016年12月05日 16:10
  • 306

CountDownLatch/CyclicBarrier/Semahore/sychronize/locy区别

CountDownLatch:线程执行完毕之后唤醒主线程往下运行 CyclicBarrier:就像栅栏一样,等所有人迈过,又回到同一起跑线之后继续走自己的路 Semahore:信号量,控制资源占用...

CountDownLatch和CyclicBarrier使用及区别

CountDownLatchCountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已...
  • yajlv
  • yajlv
  • 2017年07月20日 14:56
  • 80

join方法与countDownLatch与CyclicBarrier的区别

join方法:当前线程中调用thread.join()会导致当前线程阻塞,此时只有当thread线程执行完后,当前线程才能继续往下执行。 join的工作原理是,不停检查thread是否存活,如果存活...

cyclicbarrier countdownlatch 区别

CountDownLatch :一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。 用给定的计数 初始化 CountDownLatch。由于调用了 countDo...

Java多线程/并发24、Countdownlatch应用以及与CyclicBarrier的区别

有时候会有这样的需求:多个线程同时工作,其中几个可以随意的并发执行,但有一个线程需要等其他线程工作结束后,才能运行。举个例子,我们知道的迅雷下载,会同时开启多个线程分块下载一个大文件,每个线程下载固定...
  • soonfly
  • soonfly
  • 2017年05月07日 15:17
  • 577

CyclicBarrier和CountDownLatch区别

这两天写多线程时,用到了CyclicBarrier,下意识的认为CyclicBarrier和CountDownLatch作用很像,就翻阅资料查了一下,说一下他们的区别吧 CyclicBarr...
  • tolcf
  • tolcf
  • 2016年03月18日 19:19
  • 4954
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CountDownLatch和CyclicBarrier的区别
举报原因:
原因补充:

(最多只允许输入30个字)