CountDownLatch与CyclicBarrier使用及区别
- 开源代码
- 2025-09-17 12:51:02

CountDownLatch与CyclicBarrier使用及区别 一、`CountDownLatch`**主要用途****核心方法****使用示例**示例 1:主线程等待多个子线程完成任务示例 2:多个子线程等待主线程发出信号 **注意事项** 二、`CyclicBarrier`**主要用途****核心方法****使用示例**示例 1:多个线程相互等待示例 2:分阶段任务 **注意事项****`CyclicBarrier`与 `CountDownLatch` 的区别****适用场景** 一、CountDownLatch
java.util.concurrent.CountDownLatch 是 Java 并发编程中的一个同步工具类,用于让一个或多个线程等待其他线程完成操作后再继续执行。它的核心思想是通过一个计数器来实现线程的等待和唤醒。
主要用途
CountDownLatch 通常用于以下场景:
主线程等待多个子线程完成任务: 例如,主线程需要等待多个子线程初始化完成后才能继续执行。 多个子线程等待主线程发出信号: 例如,多个子线程需要等待主线程发出“开始”信号后才能同时执行。核心方法 CountDownLatch(int count): 构造函数,初始化计数器。count 是需要等待的操作次数。 void await(): 使当前线程等待,直到计数器减到 0。 boolean await(long timeout, TimeUnit unit): 使当前线程等待,直到计数器减到 0 或超时。 void countDown(): 将计数器减 1,表示一个操作已完成。 long getCount(): 返回当前计数器的值。
使用示例 示例 1:主线程等待多个子线程完成任务 import java.util.concurrent.CountDownLatch; public class CountDownLatchExample { public static void main(String[] args) throws InterruptedException { int threadCount = 5; CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { new Thread(() -> { System.out.println(Thread.currentThread().getName() + " 完成任务"); latch.countDown(); // 计数器减 1 }).start(); } latch.await(); // 主线程等待所有子线程完成任务 System.out.println("所有任务已完成,主线程继续执行"); } }
输出:
Thread-0 完成任务 Thread-1 完成任务 Thread-2 完成任务 Thread-3 完成任务 Thread-4 完成任务 所有任务已完成,主线程继续执行示例 2:多个子线程等待主线程发出信号 import java.util.concurrent.CountDownLatch; public class CountDownLatchExample2 { public static void main(String[] args) throws InterruptedException { int threadCount = 5; CountDownLatch startSignal = new CountDownLatch(1); for (int i = 0; i < threadCount; i++) { new Thread(() -> { try { startSignal.await(); // 子线程等待主线程的信号 System.out.println(Thread.currentThread().getName() + " 开始执行"); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } Thread.sleep(2000); // 模拟主线程准备时间 System.out.println("主线程发出开始信号"); startSignal.countDown(); // 主线程发出信号 } }
输出:
主线程发出开始信号 Thread-0 开始执行 Thread-1 开始执行 Thread-2 开始执行 Thread-3 开始执行 Thread-4 开始执行注意事项 计数器不可重置: CountDownLatch 的计数器只能减不能增,一旦计数器减到 0,就不能再使用了。如果需要重复使用,可以考虑 CyclicBarrier。 避免死锁: 确保所有线程都会调用 countDown(),否则主线程会一直等待。 性能开销: CountDownLatch 是基于 AQS(AbstractQueuedSynchronizer)实现的,性能较高,适合高并发场景。
二、CyclicBarrier
java.util.concurrent.CyclicBarrier 是 Java 并发编程中的一个同步工具类,用于让一组线程相互等待,直到所有线程都到达某个屏障点(Barrier Point)后再继续执行。与 CountDownLatch 不同,CyclicBarrier 是可以重复使用的。
主要用途
CyclicBarrier 通常用于以下场景:
多线程任务分阶段执行: 例如,多个线程需要先完成第一阶段的任务,然后同时开始第二阶段的任务。 并行计算: 例如,将一个大型计算任务拆分为多个子任务,每个子任务由一个线程处理,所有线程完成后合并结果。核心方法 CyclicBarrier(int parties): 构造函数,初始化屏障,parties 是需要等待的线程数。 CyclicBarrier(int parties, Runnable barrierAction): 构造函数,初始化屏障,并指定所有线程到达屏障后执行的操作(barrierAction)。 int await(): 使当前线程等待,直到所有线程都到达屏障。 int await(long timeout, TimeUnit unit): 使当前线程等待,直到所有线程都到达屏障或超时。 void reset(): 重置屏障,使其可以重复使用。
使用示例 示例 1:多个线程相互等待 import java.util.concurrent.CyclicBarrier; public class CyclicBarrierExample { public static void main(String[] args) { int threadCount = 3; CyclicBarrier barrier = new CyclicBarrier(threadCount, () -> { System.out.println("所有线程已到达屏障,继续执行"); }); for (int i = 0; i < threadCount; i++) { new Thread(() -> { try { System.out.println(Thread.currentThread().getName() + " 到达屏障"); barrier.await(); // 等待其他线程 System.out.println(Thread.currentThread().getName() + " 继续执行"); } catch (Exception e) { e.printStackTrace(); } }).start(); } } }
输出:
Thread-0 到达屏障 Thread-1 到达屏障 Thread-2 到达屏障 所有线程已到达屏障,继续执行 Thread-2 继续执行 Thread-0 继续执行 Thread-1 继续执行示例 2:分阶段任务 import java.util.concurrent.CyclicBarrier; public class CyclicBarrierExample2 { public static void main(String[] args) { int threadCount = 3; CyclicBarrier barrier = new CyclicBarrier(threadCount, () -> { System.out.println("当前阶段完成,进入下一阶段"); }); for (int i = 0; i < threadCount; i++) { new Thread(() -> { try { System.out.println(Thread.currentThread().getName() + " 完成阶段 1"); barrier.await(); // 等待其他线程完成阶段 1 System.out.println(Thread.currentThread().getName() + " 完成阶段 2"); barrier.await(); // 等待其他线程完成阶段 2 System.out.println(Thread.currentThread().getName() + " 完成阶段 3"); } catch (Exception e) { e.printStackTrace(); } }).start(); } } }
输出:
Thread-0 完成阶段 1 Thread-1 完成阶段 1 Thread-2 完成阶段 1 当前阶段完成,进入下一阶段 Thread-2 完成阶段 2 Thread-0 完成阶段 2 Thread-1 完成阶段 2 当前阶段完成,进入下一阶段 Thread-1 完成阶段 3 Thread-0 完成阶段 3 Thread-2 完成阶段 3注意事项 屏障点操作: 如果指定了 barrierAction,它会在最后一个线程到达屏障后执行,然后所有线程才会继续执行。 异常处理: 如果某个线程在等待时被中断或超时,屏障会被破坏,所有等待的线程会抛出 BrokenBarrierException。 重复使用: CyclicBarrier 可以重复使用,每次所有线程到达屏障后,计数器会自动重置。
CyclicBarrier与 CountDownLatch 的区别 特性CyclicBarrierCountDownLatch计数器重置可重置不可重置用途多个线程相互等待一个线程等待多个线程完成触发条件所有线程到达屏障点计数器减到 0重复使用支持不支持
适用场景 如果任务需要分阶段执行,并且每个阶段需要所有线程同步,使用 CyclicBarrier。如果只需要一个线程等待其他线程完成,使用 CountDownLatch。
CountDownLatch与CyclicBarrier使用及区别由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“CountDownLatch与CyclicBarrier使用及区别”
下一篇
LeetCode2-两数相加