码迷,mamicode.com
首页 > 其他好文 > 详细

CountDownLatch和CyclicBarrier区别及用法的demo

时间:2016-07-24 01:48:09      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:

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个线程相互等待,只要有任何一个线程没有完成,其它的N-1个线程都必须等待。
这样应该就清楚一点了,
对于CountDownLatch来说,重点是那个“一个线程, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止

而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。

 

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

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

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

http://blog.csdn.net/kjfcpua/article/details/7300286

 

用法:

一、CountDownLatch用法

  CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。

  CountDownLatch类只提供了一个构造器:

public CountDownLatch(int count) { }; //参数count为计数值

  然后下面这3个方法是CountDownLatch类中最重要的方法:

public void await() throws InterruptedException { };
//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public void countDown() { }; //将count值减1

 

二、CyclicBarrier用法

  通过它可以实现让一组线程等待至某个状态之后再全部同时执行,并且当所有等待线程都被释放以后,CyclicBarrier还可以被重用。我们暂且把这个状态就叫做barrier,当调用await()方法之后,线程就处于barrier了。

  CyclicBarrier类位于java.util.concurrent包下,CyclicBarrier提供2个构造器:

public CyclicBarrier(int parties, Runnable barrierAction) {
}
 
public CyclicBarrier(int parties) {
}

  参数parties指定让多少个线程或者任务等待至barrier状态;参数barrierAction为当这些线程都达到barrier状态时会执行的内容。

  然后CyclicBarrier中最重要的方法就是await方法,它有2个重载版本:

public int await() throws InterruptedException, BrokenBarrierException { };
public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException { };

  第一个版本比较常用,用来挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务;

  第二个版本是让这些线程等待至一定的时间,如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务。

http://www.cnblogs.com/codeOfLife/p/5687691.html

 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

public class CyclicBarrierDemo {
    private static final Logger LOGGER = LoggerFactory.getLogger(CyclicBarrierDemo.class);

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

        int count = 4;
        CountDownLatch startGate = new CountDownLatch(count);
        CyclicBarrier barrier = new CyclicBarrier(count);
        for (int i = 0; i < count; i++) {
            Thread thread = new Thread(new Writer(barrier, startGate), "demo" + i);
            thread.start();
        }

        TimeUnit.SECONDS.sleep(10);
        startGate.await();
        LOGGER.info(" ");
        LOGGER.info(" ");
        LOGGER.info("======CountDownLatch起来阻塞线程的作用======");
        LOGGER.info(" ");
        LOGGER.info(" ");
        LOGGER.info("CyclicBarrier的可重用性开始:");
        LOGGER.info(" ");
        for (int i = 0; i < count; i++) {
            Thread thread = new Thread(new Writer(barrier, startGate), "damo" + (i + 4));
            thread.start();
        }
        LOGGER.info("CountDownLatch 的count已经用完了。此处不会起到阻塞线程的作用");
    }

    static class Writer implements Runnable {
        private CyclicBarrier cyclicBarrier;
        private CountDownLatch startGate;

        public Writer(CyclicBarrier cyclicBarrier, CountDownLatch startGate) {
            this.cyclicBarrier = cyclicBarrier;
            this.startGate = startGate;
        }

        @Override
        public void run() {
            try {
                startGate.countDown();
                LOGGER.info("线程" + Thread.currentThread().getName() + "cyclicBarrier.await()前执行,等待其他线程写入完毕");
                cyclicBarrier.await();
                TimeUnit.SECONDS.sleep(5);//sleep一会。这样日志中可以很好的看到cyclicBarrier.await()的可重用性r
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            LOGGER.info(Thread.currentThread().getName() + "cyclicBarrier.await()后执行......");
        }
    }

}

Output:

[2016-07-24 00:41:25,021] [demo0][CyclicBarrierDemo] INFO - 线程demo0cyclicBarrier.await()前执行,等待其他线程写入完毕
[2016-07-24 00:41:25,025] [demo2][CyclicBarrierDemo] INFO - 线程demo2cyclicBarrier.await()前执行,等待其他线程写入完毕
[2016-07-24 00:41:25,032] [demo1][CyclicBarrierDemo] INFO - 线程demo1cyclicBarrier.await()前执行,等待其他线程写入完毕
[2016-07-24 00:41:25,033] [demo3][CyclicBarrierDemo] INFO - 线程demo3cyclicBarrier.await()前执行,等待其他线程写入完毕
[2016-07-24 00:41:30,033] [demo3][CyclicBarrierDemo] INFO - demo3cyclicBarrier.await()后执行......
[2016-07-24 00:41:30,035] [demo2][CyclicBarrierDemo] INFO - demo2cyclicBarrier.await()后执行......
[2016-07-24 00:41:30,035] [demo0][CyclicBarrierDemo] INFO - demo0cyclicBarrier.await()后执行......
[2016-07-24 00:41:30,039] [demo1][CyclicBarrierDemo] INFO - demo1cyclicBarrier.await()后执行......
[2016-07-24 00:41:35,011] [main][CyclicBarrierDemo] INFO -  
[2016-07-24 00:41:35,011] [main][CyclicBarrierDemo] INFO -  
[2016-07-24 00:41:35,012] [main][CyclicBarrierDemo] INFO - ======CountDownLatch起来阻塞线程的作用======
[2016-07-24 00:41:35,012] [main][CyclicBarrierDemo] INFO -  
[2016-07-24 00:41:35,012] [main][CyclicBarrierDemo] INFO -  
[2016-07-24 00:41:35,012] [main][CyclicBarrierDemo] INFO - CyclicBarrier的可重用性开始:
[2016-07-24 00:41:35,012] [main][CyclicBarrierDemo] INFO -  
[2016-07-24 00:41:35,017] [damo4][CyclicBarrierDemo] INFO - 线程damo4cyclicBarrier.await()前执行,等待其他线程写入完毕
[2016-07-24 00:41:35,017] [main][CyclicBarrierDemo] INFO - CountDownLatch 的count已经用完了。此处不会起到阻塞线程的作用
[2016-07-24 00:41:35,017] [damo6][CyclicBarrierDemo] INFO - 线程damo6cyclicBarrier.await()前执行,等待其他线程写入完毕
[2016-07-24 00:41:35,017] [damo5][CyclicBarrierDemo] INFO - 线程damo5cyclicBarrier.await()前执行,等待其他线程写入完毕
[2016-07-24 00:41:35,017] [damo7][CyclicBarrierDemo] INFO - 线程damo7cyclicBarrier.await()前执行,等待其他线程写入完毕
[2016-07-24 00:41:40,017] [damo7][CyclicBarrierDemo] INFO - damo7cyclicBarrier.await()后执行......
[2016-07-24 00:41:40,017] [damo6][CyclicBarrierDemo] INFO - damo6cyclicBarrier.await()后执行......
[2016-07-24 00:41:40,017] [damo4][CyclicBarrierDemo] INFO - damo4cyclicBarrier.await()后执行......
[2016-07-24 00:41:40,018] [damo5][CyclicBarrierDemo] INFO - damo5cyclicBarrier.await()后执行......

 

demo

 

CountDownLatch和CyclicBarrier区别及用法的demo

标签:

原文地址:http://www.cnblogs.com/softidea/p/5699964.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!