• 注册
当前位置:1313e > 默认分类 >正文

CountDownLatch与CyclicBarrier的使用与区别

CountDownLatch与CyclicBarrier的使用与区别

CountDownLatch的介绍和使用:

一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达0之前,await 方法会一直受阻塞。

之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。

使用场景:

在一些应用场合中,需要等待某个条件达到要求后才能做后面的事情;同时当线程都完成后也会触发事件,以便进行后面的操作。

这个时候就可以使用CountDownLatch。CountDownLatch最重要的方法是countDown()和await(),前者主要是倒数一次,后者是等待倒数到0,如果没有到达0,就只有阻塞等待了。

相关实例

// 一个CountDouwnLatch实例是不能重复使用的,也就是说它是一次性的,锁一经被打开就不能再关闭使用了,如果想重复使用,请考虑使用CyclicBarrier。
public class CountDownLatchTest {// 模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束。public static void main(String[] args) throws InterruptedException {// 开始的倒数锁 final CountDownLatch begin = new CountDownLatch(1);  // 结束的倒数锁 final CountDownLatch end = new CountDownLatch(10);  // 十名选手 final ExecutorService exec = Executors.newFixedThreadPool(10);  for (int index = 0; index < 10; index++) {final int NO = index + 1;  Runnable run = new Runnable() {public void run() {  try {  // 如果当前计数为零,则此方法立即返回。// 等待
                        begin.await();  Thread.sleep((long) (Math.random() * 10000));  System.out.println("No." + NO + " arrived");  } catch (InterruptedException e) {  } finally {  // 每个选手到达终点时,end就减一
                        end.countDown();}  }  };  exec.submit(run);}  System.out.println("Game Start");  // begin减一,开始游戏
        begin.countDown();  // 等待end变为0,即所有选手到达终点
        end.await();  System.out.println("Game Over");  exec.shutdown();  }
}

 

以上实例转自:http://www.itzhai.com/the-introduction-and-use-of-a-countdownlatch.html

CyclicBarrier和CountDownLatch一样,都是关于线程的计数器。

用法略有不同,测试代码如下:

public class TestCyclicBarrier {private static final int THREAD_NUM = 5;    public static class WorkerThread implements Runnable{CyclicBarrier barrier;public WorkerThread(CyclicBarrier b){this.barrier = b;}public void run() {try{System.out.println("Worker's waiting");//线程在这里等待,直到所有线程都到达barrier。
                barrier.await();System.out.println("ID:"+Thread.currentThread().getId()+" Working");}catch(Exception e){e.printStackTrace();}}}public static void main(String[] args) {CyclicBarrier cb = new CyclicBarrier(THREAD_NUM, new Runnable() {//当所有线程到达barrier时执行public void run() {System.out.println("Inside Barrier");}});for(int i=0;i){new Thread(new WorkerThread(cb)).start();}}}
/*
以下是输出:
Worker's waiting
Worker's waiting
Worker's waiting
Worker's waiting
Worker's waiting
Inside Barrier
ID:12 Working
ID:8 Working
ID:11 Working
ID:9 Working
ID:10 Working
*/

 

  1.  CyclicBarrier初始化时规定一个数目,然后计算调用了CyclicBarrier.await()进入等待的线程数。当线程数达到了这个数目时,所有进入等待状态的线程被唤醒并继续。 
  2.  CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 
  3.  CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行

两者区别

http://xumingming.sinaapp.com/215/countdownlatch-vs-cyclicbarrier/

posted on 2014-01-06 00:24 pingh14 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/pingh/p/3506493.html

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 162202241@qq.com 举报,一经查实,本站将立刻删除。

最新评论

欢迎您发表评论:

请登录之后再进行评论

登录