CountDownLatch(减法计数器)-CyclicBarrier(加法计数器)

1.CountDownLatch

允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。
public CountDownLatch(int count)构造一个以给定计数
CountDownLatch CountDownLatch。
参数
count -的次数 countDown()必须调用之前线程可以通过 await()
异常
IllegalArgumentException - 如果 count为负数

public void countDown()

减少锁存器的计数,如果计数达到零,释放所有等待的线程。
如果当前计数大于零,则它将递减。 如果新计数为零,则所有等待的线程都将被重新启用以进行线程调度。
如果当前计数等于零,那么没有任何反应。
public void await()

throws InterruptedException

导致当前线程等到锁存器计数到零,除非线程是interrupted 。
如果当前计数为零,则此方法立即返回。

示例:

CountDownLatch countDownLatch = new CountDownLatch(10);
for(int i = 0;i<10;i++){
    new Thread(()->{
        System.out.println(Thread.currentThread().getName()+"***");
        countDownLatch.countDown();//数量-1
    },String.valueOf(i)).start();
}
countDownLatch.await();     //等待计数器变为0结束
System.out.println("end");

2.CyclicBarrier

允许一组线程全部等待彼此达到共同屏障点的同步辅助。 循环阻塞在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此。 屏障被称为循环 ,因为它可以在等待的线程被释放之后重新使用。
A CyclicBarrier支持一个可选的Runnable命令,每个屏障点运行一次,在派对中的最后一个线程到达之后,但在任何线程释放之前。 在任何一方继续进行之前,此屏障操作对更新共享状态很有用。

await如果当前线程不是最后一个线程,那么它被禁用以进行线程调度,并且处于休眠状态,直到发生下列事情之一await

最后一个线程到达; 要么
一些其他线程当前线程为interrupts ; 要么
一些其他线程interrupts其他等待线程之一; 要么
一些其他线程在等待屏障时超时; 要么
其他一些线程在这个屏障上调用reset() 。
示例`

CyclicBarrier cyclicBarrier = new CyclicBarrier(8);   //线程达到8才结束
        for (int i = 0;i<8;i++){
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"***");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
### CountDownLatch 的使用方法 `CountDownLatch` 是 Java 并发包中的一个同步辅助类,主要用于协调多个线程之间的操作。它的核心是一个计数器,该计数器的初始值由构造函数设定。每当调用 `countDown()` 方法时,计数器就会减少 1。当计数器达到零时,所有因调用了 `await()` 而被阻塞的线程将会被唤醒并继续执行。 以下是 `CountDownLatch` 的基本使用方式: #### 构造方法 ```java public CountDownLatch(int count); ``` 参数 `count` 表示计数器的初始值。 #### 关键方法 - **`void await()`**: 当前线程进入等待状态,直到计数器变为 0 或超时。 - **`boolean await(long timeout, TimeUnit unit)`**: 让当前线程在指定的时间范围内等待,如果时间到了还没有满足条件,则返回 false。 - **`void countDown()`**: 将计数器减 1。 #### 示例代码 ```java import java.util.concurrent.CountDownLatch; public class CountDownLatchExample { public static void main(String[] args) throws InterruptedException { int threadCount = 3; CountDownLatch latch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { Thread worker = new Thread(() -> { System.out.println(Thread.currentThread().getName() + " is working."); try { Thread.sleep(1000); // Simulate work } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " finished its job."); latch.countDown(); // Decrease the counter after finishing task. }); worker.start(); } System.out.println("Main thread waiting..."); latch.await(); // Main thread waits until all workers finish their jobs. System.out.println("All threads have completed their tasks."); } } ``` --- ### CountDownLatchCyclicBarrier 的区别对比 尽管两者都属于 Java 并发工具类,并且都能用于线程间的协作,但它们的设计目标和适用场景存在显著差异。 | 特性 | CountDownLatch[^2] | CyclicBarrier[^3] | |--------------------------|---------------------------------------------|----------------------------------------| | **主要用途** | 协调单个线程等待多个线程完成任务 | 多个线程相互等待至某一屏障点后再一起行动 | | **是否可复用** | 不可复用 | 支持复用 | | **阻塞行为** | 调用 `await()` 阻塞主线程 | 所有参与线程都会因为 `await()` 被阻塞 | | **计数器变化方式** | 每次调用 `countDown()` 减少 | 每次调用 `await()` 自动增加 | | **额外功能支持** | 较少 | 提供如 `getNumberWaiting()` 和 `isBroken()` 等方法 | 具体来说: - **CountDownLatch** 更适合于一种“主从模型”,其中有一个线程作为主导者,需要等待其他几个工作线程完成后才能继续其逻辑。 - **CyclicBarrier** 则适用于一组线程之间彼此依赖的情况,只有当所有成员均抵达特定阶段后才可以共同推进下一步动作[^3]。 另外,在内部实现方面,`CyclicBarrier` 使用了 ReentrantLock 和 Condition 来管理线程间的关系及其状态转换过程[^4];而 `CountDownLatch` 的底层则是基于 AQS(AbstractQueuedSynchronizer)[^3] 实现的锁机制。 --- ### 总结 对于希望某些操作仅能在一系列前置条件完全达成之后才得以开展的应用场合而言,“倒计时门闩”——也就是我们所说的 `CountDownLatch` ——无疑是非常理想的选择之一[^1]。然而若是面对那些要求各路进程齐头并进直至碰面再联合向前迈进的情形的话,则应该考虑采用 “循环栅栏” (`CyclicBarrier`) 进行处理。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值