CountDownLatch & CyclicBarrier

CyclicBarrier    一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环的barrier。 
 
CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作很有用。
 
如果屏障操作在执行时不依赖于正挂起的线程,则线程组中的任何线程在获得释放时都能执行该操作。为方便此操作,每次调用 await() 都将返回能到达屏障处的线程的索引。然后,您可以选择哪个线程应该执行屏障操作,例如: 
if (barrier.await() == 0) {
// log the completion of this iteration
}
对于失败的同步尝试,CyclicBarrier 使用了一种要么全部要么全不 (all-or-none) 的破坏模式:如果因为中断、失败或者超时等原因,导致线程过早地离开了屏障点,那么在该屏障点等待的其他所有线程也将通过 BrokenBarrierException(如果它们几乎同时被中断,则用 InterruptedException)以反常的方式离开。
 
public int await() throws InterruptedException, BrokenBarrierException
在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。 
如果当前线程不是将到达的最后一个线程,出于调度目的,将禁用它,且在发生以下情况之一前,该线程将一直处于休眠状态: 
  • 最后一个线程到达;或者 
  • 其他某个线程中断当前线程;或者 
  • 其他某个线程中断另一个等待线程;或者 
  • 其他某个线程在等待 barrier 时超时;或者 
  • 其他某个线程在此 barrier 上调用 reset()。 
如果当前线程: 则抛出 InterruptedException,并且清除当前线程的已中断状态。 
  • 在进入此方法时已经设置了该线程的中断状态;
  • 或者 在等待时被中断 

 

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

CountDownLatch是一次性的,而CyclicBarrier在调用reset之后还可以继续使用。

posted on 2018-08-29 15:03  xiaowater  阅读(81)  评论(0)    收藏  举报

导航