CyclicBarrier和CountDownLatch的区别

从网上搜到的文章,在讲到这两者的区别时,大多都引用了以下两句话:

(01) CountDownLatch的作用是允许1或N个线程等待其他线程完成执行;而CyclicBarrier则是允许N个线程相互等待。
(02) CountDownLatch的计数器无法被重置;CyclicBarrier的计数器可以被重置后使用,因此它被称为是循环的barrier。

但看完这两句话,从代码角度出发,这两者的区别我一直没有理解。1个线程等待其他线程,和N个线程相互等待,其实从某种角度来讲,意义是差不多的,总归都是到达某个触发点之后,执行所有线程。所以从我个人的角度出发,我觉得第一点更多时候只是意义上的差别,在功能上似乎没有什么区别。(如果各位有什么看法,请指正。)

然后我试下来,我认为两者的关键区别在于第二点,CountDownLatch一旦计数器到0,后面的线程不会再等待,无条件执行,而对于CyclicBarrier,第一轮的数量满足后,第二轮也必须达到指定的数量,才会再次执行。换成代码如下所示:

<<CountDownLatch>>

final int threadCount = 3;
ExecutorService service = Executors.newFixedThreadPool(threadCount);
CompletionService<Patient> completionService = new ExecutorCompletionService<Patient>(service);

final CountDownLatch latch = new CountDownLatch(threadCount);

//以下遍历过过程故意将threadCount+2,会发现当 i = threadCount - 1时,
//就会触发latch的执行,for循环后续的几个线程(threadCount, threacCount + 1)会直接执行,
//没有任何等待,因为latch已经到达0了,不再有任何作用了。
for (int i = 0; i < threadCount + 2; i++) {
  completionService.submit(new Callable<String>() {
      public String call() throws Exception {
         latch.countDown();
         latch.await();
         return "test message";
      }
  }
}

 

那么对于CyclicBarrier而言,执行过程有所不同

final int threadCount = 3;
ExecutorService service = Executors.newFixedThreadPool(threadCount);
CompletionService<Patient> completionService = new ExecutorCompletionService<Patient>(service);

final CyclicBarrier barrier = new CyclicBarrier(threadCount);

//以下遍历过过程故意将threadCount+2,会发现当 i = threadCount - 1时,
//就会触发barrier的执行,但是for循环后续的几个线程(threadCount, threacCount + 1)会一直等待,
//因为数量是2,没有达到执行点。也就是说CyclicBarrier是循环起作用的,这个是与CountDownLatch的重要区别
for (int i = 0; i < threadCount + 2; i++) {
  completionService.submit(new Callable<String>() {
      public String call() throws Exception {
         barrier.await();
         return "test message";
      }
  }
}

 

所以我觉得之前说的第2点,用我的理解来描述的话,应该是这样:

(02) CountDownLatch的计数器一旦为0,无法被重置,失去原有的作用;CyclicBarrier的计数器可以被循环使用,一次循环结束后,可以继续给下一次的循环使用。

以上是根据之前试验得出来的两者之间在使用上的差别,至于其他方面还有什么差别,暂时没有深入研究,后面有时间再继续吧。

猜你喜欢

转载自garyjiao.iteye.com/blog/2243260