推荐答案
CountDownLatch 和 CyclicBarrier 都是 Java 并发包中用于线程同步的工具类,但它们的使用场景和机制有所不同。
CountDownLatch:
- 用于一个或多个线程等待其他线程完成操作。
- 初始化时指定一个计数值,线程通过调用
countDown()方法减少计数值,当计数值减到 0 时,等待的线程被唤醒。 - 计数值不可重置,一旦减到 0,就不能再次使用。
CyclicBarrier:
- 用于多个线程相互等待,直到所有线程都到达某个屏障点。
- 初始化时指定参与线程的数量,线程通过调用
await()方法等待,当所有线程都到达屏障点时,屏障打开,所有线程继续执行。 - 屏障可以重复使用,即所有线程到达屏障点后,屏障会自动重置,可以再次使用。
本题详细解读
CountDownLatch
CountDownLatch 是一个同步辅助类,允许一个或多个线程等待其他线程完成操作。它通过一个计数器来实现,计数器的初始值由构造函数指定。每当一个线程完成了自己的任务后,调用 countDown() 方法将计数器减 1。当计数器减到 0 时,所有等待的线程(通过 await() 方法等待的线程)将被唤醒并继续执行。
CountDownLatch 的典型使用场景是主线程等待多个子线程完成任务后再继续执行。例如,主线程启动多个子线程执行任务,然后调用 await() 方法等待所有子线程完成任务后再继续执行后续操作。
CyclicBarrier
CyclicBarrier 也是一个同步辅助类,但它允许多个线程相互等待,直到所有线程都到达某个屏障点(barrier point)。CyclicBarrier 的构造函数需要指定参与线程的数量,每个线程通过调用 await() 方法表示自己已经到达屏障点,并等待其他线程到达。
当所有线程都到达屏障点时,屏障打开,所有线程继续执行。与 CountDownLatch 不同的是,CyclicBarrier 的屏障可以重复使用,即所有线程到达屏障点后,屏障会自动重置,可以再次使用。
CyclicBarrier 的典型使用场景是多个线程需要相互等待,直到所有线程都完成某个阶段的任务后再继续执行。例如,多个线程分别计算数据的一部分,然后等待所有线程都完成计算后再进行下一步操作。
区别总结
使用场景:
CountDownLatch适用于一个或多个线程等待其他线程完成操作。CyclicBarrier适用于多个线程相互等待,直到所有线程都到达某个屏障点。
计数器:
CountDownLatch的计数器不可重置,一旦减到 0,就不能再次使用。CyclicBarrier的屏障可以重复使用,所有线程到达屏障点后,屏障会自动重置。
线程行为:
CountDownLatch的线程通过countDown()方法减少计数器,通过await()方法等待计数器减到 0。CyclicBarrier的线程通过await()方法等待其他线程到达屏障点。