Java中的CountDownLatch与CyclicBarrier
CountDownLatch和CyclicBarrier都是Java并发中的同步辅助工具,可促进线程之间的通信。这两个同步辅助工具都创建了一个闩锁或者一个屏障,以使线程等待直到满足条件,然后只有线程才能进行进一步的处理。在本文中,我们将看到CountDownLatch和CyclicBarrier在Java中的区别。
CountDownLatch和CyclicBarrier
- CyclicBarrier –同步帮助,它允许一组线程互相等待以到达一个公共的障碍点。
- CountDownLatch –同步帮助,它允许一个或者多个线程等待,直到在其他线程中执行的一组操作完成。
Java中的CountDownLatch与CyclicBarrier
1初始化:
CountDownLatch用给定的count初始化,其中count表示在线程可以通过await()之前必须调用countDown()的次数。
CyclicBarrier用给定数量的参与者初始化,其中party表示线程数,当给定数量的参与者(线程)在等待它时CyclicBarrier跳闸。
这种初始化使CountDownLatch更具通用性的同步工具
- 以1计数初始化的CountDownLatch用作简单的开/关闩锁或者门:所有调用await的线程都在门处等待,直到被调用countDown()的线程打开为止。
- 初始化为N的CountDownLatch可用于使一个线程等待,直到N个线程已完成某些操作或者某些操作已完成N次。
使用CyclicBarrier可以指定正在等待的线程数,这意味着如果将CyclicBarrier初始化为3,则3个线程应在此屏障上调用await()来使屏障跳闸。这使得CyclicBarrier对于涉及固定大小的线程方(偶尔必须互相等待)的场景更加有用。
2可重用性:
CountDownLatch和CyclicBarrier之间的主要区别之一是CountDownLatch无法重复使用。一旦CountDownLatch实例的计数达到零,就无法重置计数。
释放等待线程后,可以重新使用CyclicBarrier。
3可选的Runnable:
CyclicBarrier类具有一个构造函数,可以在其中提供Runnable barrierAction。
public CyclicBarrier(int parties, Runnable barrierAction)
给定的屏障操作在屏障被触发时执行,由进入屏障的最后一个线程执行。
因此,可以选择使用CyclicBarrier执行单独的Runnable操作。
Java中的CountDownLatch类没有任何此类构造函数来指定可运行的操作。
4例外:
CyclicBarrier对失败的同步尝试使用全有或者无损坏模型:如果线程由于中断,失败或者超时而过早离开障碍点,则所有其他在该障碍点等待的线程也会通过BrokenBarrierException(或者InterruptedException)异常离开如果它们也大约同时被打断了)。
如果有任何线程在等待时被中断,则所有其他等待线程将抛出BrokenBarrierException,并且屏障处于断开状态。
如果在任何线程正在等待时重设了barrier(屏障),或者在调用await或者任何线程正在等待时打破了屏障,则将抛出BrokenBarrierException。
使用CountDownLatch如果当前线程在等待时被中断,则抛出InterruptedException。