Java中CyclicBarrier 和 CountDownLatch有什么不同?
CyclicBarrier
和 CountDownLatch
是 Java 中用于线程同步的两种工具,它们在使用场景和行为上有一些显著的不同点。
CyclicBarrier:
CyclicBarrier
是一个同步辅助类,允许一组线程互相等待,直到所有线程都到达某个公共屏障点。它可以被重用,即在所有线程到达屏障后,可以重新开始新的计数。CountDownLatch:
CountDownLatch
是一个同步辅助类,允许一个或多个线程等待直到在其他线程中执行的一组操作完成。它的计数器在初始化时设定,随着线程的完成而递减,直到计数器为零,所有等待的线程才会被释放。CyclicBarrier:
CyclicBarrier
。CountDownLatch:
CountDownLatch
就不能再被使用。countDown()
,然后才能释放等待的线程。CyclicBarrier:
await()
方法时会被阻塞,直到所有线程都到达屏障。Runnable
任务。CountDownLatch:
await()
方法时会被阻塞,直到计数器减到零。CyclicBarrier:
CountDownLatch:
CyclicBarrier 示例:
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("所有线程到达屏障,继续执行");
});
Runnable task = () -> {
try {
System.out.println(Thread.currentThread().getName() + " 到达屏障");
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
};
new Thread(task).start();
new Thread(task).start();
new Thread(task).start();
}
}
CountDownLatch 示例:
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
Runnable task = () -> {
try {
System.out.println(Thread.currentThread().getName() + " 完成任务");
latch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
};
new Thread(task).start();
new Thread(task).start();
new Thread(task).start();
latch.await(); // 等待计数器为零
System.out.println("所有线程完成,继续执行");
}
}
总结来说,CyclicBarrier
和 CountDownLatch
各有其适用场景,选择合适的工具可以更好地实现线程间的同步。