请描述 Java 中 CyclicBarrier 的作用与使用方式,并说明它与 CountDownLatch 的主要区别。
考察说明
考查候选人是否真正理解 CyclicBarrier 的同步机制及其与 CountDownLatch 的差异。
回答思路
- 【回答框架 1】CyclicBarrier 是 Java 并发包中的同步工具,用于让一组线程互相等待,直到所有线程都到达某个公共屏障点后,它们才能继续执行。它支持在屏障点执行一个可选的 Runnable 命令,该命令在所有线程到达后、任一线程放行前运行。
- 【回答框架 2】其核心机制是计数等待:构造时传入 parties 数量,每个线程调用 await() 后计数减一并阻塞,当计数归零时屏障打开,所有等待线程被唤醒并继续。关键特性是可循环使用,与 CountDownLatch 不同,且每个线程在屏障处等待时也可被中断或设置超时。
- 【回答框架 3】与 CountDownLatch 相比,CyclicBarrier 的计数是固定的,且所有线程必须同时到达才能放行,而 CountDownLatch 只需调用 countDown() 使计数归零即可,不要求所有参与的线程都调用。此外,CyclicBarrier 可重置复用,CountDownLatch 不可复用。应用场景上,CyclicBarrier 适合多个线程分阶段处理任务后互相等待,CountDownLatch 适合等待一个或多个事件完成。
- 【回答框架 4】使用 CyclicBarrier 时需注意线程数设置与参与线程数匹配,否则可能永远等待;还需处理 BrokenBarrierException 和 InterruptedException,关注屏障重置和损坏状态。
- 【关键点 1】CyclicBarrier 让一组线程互相等待到达公共屏障后再继续,支持循环使用。
- 【关键点 2】其内部使用计数器,当计数器为零时打开屏障并执行可选的 barrierAction(如果存在)。
- 【关键点 3】与 CountDownLatch 的区别在于:CyclicBarrier 必须所有线程都到达,且可复用;CountDownLatch 是倒数计数,只需计数归零,不可复用。
- 【关键点 4】使用时应确保参与线程数与构造参数一致,并处理中断异常和屏障损坏状态。
- 【关键点 5】CyclicBarrier 适合任务分阶段执行且各阶段需同步,CountDownLatch 适合等待多个独立事件全部完成。
- 【易错点 1】误以为 CyclicBarrier 与 CountDownLatch 等价,导致选错工具;实际上前者是等待线程集合,后者是等待计数归零。
- 【易错点 2】忽略屏障损坏状态,当线程在等待中被中断或超时时,会抛出 BrokenBarrierException,需在代码中处理。
- 【易错点 3】线程数不匹配或线程提前退出,可能导致所有线程永远等待,因此需要合理设置参与线程数。