CountDownLatch 和 CyclicBarrier的区别和详解
CountDownLatch 和 CyclicBarrier 都是 Java 并发编程中的同步工具,它们都用于线程间的同步和协调。然而,它们的实现方式和使用场景有一些不同。
CountDownLatch 是一个计数器,它用于表示某个操作需要等待其他线程完成。当 CountDownLatch 初始化时,它的计数器会被设置为一个指定的值,每个线程可以调用 CountDownLatch 的 await() 方法来等待计数器减 1。只有当计数器减为 0 时,线程才能继续执行。CountDownLatch 是一个独占锁,也就是说,当一个线程调用 await() 方法时,其他线程需要等待该线程释放锁后才能继续执行。
CyclicBarrier 是一个可重用的屏障,它用于表示某个操作需要等待其他线程完成。当 CyclicBarrier 初始化时,它的计数器会被设置为一个指定的值,每个线程可以调用 CyclicBarrier 的 await() 方法来等待计数器减 1。只有当计数器减为 0 时,线程才能继续执行。与 CountDownLatch 不同,CyclicBarrier 是一个共享锁,也就是说,当一个线程调用 await() 方法时,其他线程可以继续执行,只有当前线程需要等待。
总的来说,CountDownLatch 和 CyclicBarrier 的区别主要体现在两个方面:
锁的类型不同:CountDownLatch 是一个独占锁,而 CyclicBarrier 是一个共享锁。
使用场景不同:CountDownLatch 通常用于需要等待其他线程完成的场景,而 CyclicBarrier 通常用于需要等待其他线程完成多次操作的场景。
下面是一个简单的示例代码,用于说明 CountDownLatch 和 CyclicBarrier 的使用方法:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
public class Demo {
private static final int COUNT = 5;
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(COUNT);
CyclicBarrier cyclicBarrier = new CyclicBarrier(COUNT);
Thread[] threads = new Thread[COUNT];
for (int i = 0; i < COUNT; i++) {
threads[i] = new Thread(() -> {
try {
countDownLatch.await();
System.out.println("CountDownLatch finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
threads[i].start();
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
cyclicBarrier.await();
System.out.println("CyclicBarrier finished");
}
}
在这个示例代码中,我们使用了 CountDownLatch 和 CyclicBarrier 来实现线程同步。CountDownLatch 用于等待其他线程完成,而 CyclicBarrier 用于等待其他线程完成多次操作。
