读懂CountDownLatch、CyclicBarrier、Semaphore的用法与区别
2023-11-29 07:09:42
前言
在Java并行编程中,经常需要使用等待机制来实现线程之间的同步和通信。CountDownLatch、CyclicBarrier和Semaphore都是常用的等待机制,它们都可以在一个线程等待另一个线程或一组线程完成任务时挂起,直到所有任务都完成。
CountDownLatch
CountDownLatch是一个简单的等待机制,它允许一个线程等待一组其他线程完成任务。CountDownLatch使用一个计数器来记录需要完成的任务数量,每个任务完成时调用countDown()方法来减少计数器。当计数器减少到0时,等待的线程将被唤醒。
CountDownLatch非常适合用于需要等待一组任务全部完成的场景,例如:
- 在主线程等待所有子线程完成任务后继续执行。
- 在一个线程等待另一个线程执行完某个操作后继续执行。
- 在一个线程等待一组任务全部完成并收集任务的结果。
CyclicBarrier
CyclicBarrier是一个更复杂的等待机制,它允许一组线程等待所有线程都到达某个点后再继续执行。CyclicBarrier使用一个计数器来记录等待的线程数量,每个线程到达时调用await()方法来增加计数器。当计数器达到某个预定的值时,所有等待的线程将被唤醒。
CyclicBarrier非常适合用于需要等待一组线程全部到达某个点的场景,例如:
- 在一组线程全部完成初始化后开始执行任务。
- 在一组线程全部完成任务后开始下一轮任务。
- 在一组线程全部到达某个检查点后继续执行。
Semaphore
Semaphore是一个更通用的等待机制,它允许一个线程等待另一个线程或一组线程释放一个许可证。Semaphore使用一个许可证计数器来记录可用的许可证数量,每个线程需要一个许可证才能执行任务。当许可证计数器减少到0时,等待的线程将被挂起,直到有许可证可用。
Semaphore非常适合用于需要控制并发线程数量的场景,例如:
- 限制同时访问共享资源的线程数量。
- 控制并发任务的数量。
- 实现生产者消费者模式。
区别
CountDownLatch、CyclicBarrier和Semaphore这三种等待机制都有自己的特点和适用场景,它们的主要区别如下:
- CountDownLatch只能等待一组任务全部完成一次,而CyclicBarrier和Semaphore可以等待一组任务多次完成。
- CountDownLatch只能用于等待任务完成,而CyclicBarrier和Semaphore还可以用于控制并发线程的数量。
- CountDownLatch和CyclicBarrier都是基于计数器的等待机制,而Semaphore是基于许可证的等待机制。
总结
CountDownLatch、CyclicBarrier和Semaphore都是Java并行编程中常用的等待机制,它们都有各自的特点和适用场景。在实际项目中,应该根据具体需求选择最合适的等待机制。