功能区别
- CyclicBarrier:
- 它允许一组线程互相等待,直到到达某个公共屏障点(barrier point)。所有线程到达屏障点后,这些线程会被释放,继续执行后续代码。
- 它是可循环使用的,即所有线程通过屏障后,CyclicBarrier可以被重置并再次使用。
- CountDownLatch:
- 它是一个计数器,通过
countDown()
方法递减计数,当计数减到0时,等待在await()
方法上的线程会被释放。
- 它是一次性的,一旦计数为0,不能再次重置计数器重新使用。
使用方式区别
- CyclicBarrier:
- 构造函数通常接受一个整数参数
parties
,表示需要在屏障点等待的线程数量。例如:CyclicBarrier barrier = new CyclicBarrier(3);
- 线程调用
barrier.await()
方法来表明自己已经到达屏障点,所有线程都调用await()
后,它们会同时被释放。
- 可以提供一个可选的
Runnable
任务作为构造函数参数,该任务会在所有线程到达屏障后执行一次。例如:
CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("All threads have reached the barrier"));
- CountDownLatch:
- 构造函数接受一个整数参数
count
,初始化计数器的值。例如:CountDownLatch latch = new CountDownLatch(5);
- 主线程或其他需要等待的线程调用
latch.await()
方法等待计数器归零。
- 工作线程完成任务后调用
latch.countDown()
方法递减计数器。例如:
new Thread(() -> {
// 执行任务
latch.countDown();
}).start();
应用场景区别
- CyclicBarrier:
- 适用于需要多线程协作完成某个阶段任务,然后一起进入下一阶段的场景。比如在并行计算中,多个线程分别处理数据的不同部分,当所有线程都完成各自的计算后,一起进行结果汇总和下一步处理。
- 例如,模拟多辆赛车同时出发,当所有赛车都到达某个检查点后,一起重新出发前往下一段赛程。
- CountDownLatch:
- 适用于一个或多个线程需要等待其他一组线程完成操作后才能继续执行的场景。比如主线程等待所有子线程完成数据加载后,再进行数据处理。
- 例如,在分布式系统中,主线程等待所有子节点完成初始化后,再启动系统服务。