倒计时器CountDownLatch举例分析

发布时间:2021-12-14 15:13:52 作者:iii
来源:亿速云 阅读:130
# 倒计时器CountDownLatch举例分析

## 一、CountDownLatch概述

`CountDownLatch`是Java并发包(`java.util.concurrent`)中的一个同步工具类,它允许一个或多个线程等待其他线程完成操作后再继续执行。其核心思想是通过一个计数器来实现线程间的协调,当计数器归零时,等待的线程将被唤醒。

### 核心方法
- `CountDownLatch(int count)`:构造函数,初始化计数器
- `countDown()`:计数器减1
- `await()`:阻塞当前线程直到计数器归零

## 二、典型应用场景

1. **主线程等待子线程初始化完成**
2. **并行任务同步**
3. **模拟高并发测试**
4. **服务启动前的依赖检查**

## 三、代码示例分析

### 场景模拟:赛跑比赛
假设有5名运动员参赛,裁判需要等待所有运动员到达终点后才能宣布比赛结束。

```java
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class RaceExample {
    public static void main(String[] args) throws InterruptedException {
        final int RUNNER_COUNT = 5;
        CountDownLatch startSignal = new CountDownLatch(1);  // 发令枪
        CountDownLatch finishSignal = new CountDownLatch(RUNNER_COUNT);  // 终点线
        
        for (int i = 1; i <= RUNNER_COUNT; i++) {
            new Thread(new Runner(startSignal, finishSignal, "运动员"+i)).start();
        }
        
        System.out.println("裁判准备发令...");
        TimeUnit.SECONDS.sleep(2);  // 模拟准备时间
        startSignal.countDown();     // 发令枪响
        System.out.println("比赛开始!");
        
        finishSignal.await();        // 等待所有运动员到达终点
        System.out.println("所有运动员到达终点,比赛结束!");
    }
}

class Runner implements Runnable {
    private final CountDownLatch startSignal;
    private final CountDownLatch finishSignal;
    private final String name;
    
    public Runner(CountDownLatch start, CountDownLatch finish, String name) {
        this.startSignal = start;
        this.finishSignal = finish;
        this.name = name;
    }
    
    @Override
    public void run() {
        try {
            startSignal.await();  // 等待发令枪
            
            System.out.println(name + "起跑...");
            TimeUnit.MILLISECONDS.sleep((long)(Math.random() * 3000));  // 模拟跑步时间
            System.out.println(name + "到达终点!");
            
            finishSignal.countDown();  // 到达终点计数器减1
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

执行结果示例:

裁判准备发令...
比赛开始!
运动员1起跑...
运动员3起跑...
运动员5起跑...
运动员2起跑...
运动员4起跑...
运动员3到达终点!
运动员1到达终点!
运动员5到达终点!
运动员2到达终点!
运动员4到达终点!
所有运动员到达终点,比赛结束!

四、实现原理

  1. AQS基础:基于AbstractQueuedSynchronizer实现
  2. 共享锁模式:所有等待线程共享同一个同步状态
  3. 不可重置:计数器归零后无法重复使用(与CyclicBarrier的主要区别)

五、注意事项

  1. 避免死锁:确保countDown()一定会被执行
  2. 性能考虑:计数器初始值不宜过大
  3. 异常处理:中断处理需要谨慎
  4. 不可重用:需要重复使用时考虑CyclicBarrier

六、与相关类的对比

特性 CountDownLatch CyclicBarrier Semaphore
是否可重用
主要作用 等待事件完成 线程集合点 控制并发量
计数器变化方向 递减 递增 可增可减
触发动作 计数到0自动触发 到达屏障数执行回调 获取/释放许可

七、总结

CountDownLatch是解决多线程协同问题的有效工具,特别适用于”主从协作”模式。理解其原理和适用场景,可以帮助我们编写更健壮的并发程序。在实际开发中,应根据具体需求选择合适的同步工具。 “`

推荐阅读:
  1. mysql举例分析
  2. CountDownLatch了解

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

countdownlatch

上一篇:django中的时间段查询应该如何处理

下一篇:iBash4J部署时启动项目连接不上Redis无法从JedisPool中获取连接该怎么办

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》