CountDownLatch应用场景代码练习

概念原理

  • CountDownLatchjuc(java.util.concurrent)包里的一个工具类,还有一起的CycliBarrierSemaphore
  • CountDownLatch这个类的作用是让 一个主线程 等待其他子线程执行完毕后再执行。
  • 通过一个计数器count来实现的,计数器的初始值是子线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。
  • 注意:CountDownLatch 是一次性的,不能 reset count 值

核心参数和方法

在这里插入图片描述

  • 一个核心参数
    • count,记录子线程的个数
  • 两个核心方法
    • countDown(),让 count-1
    • await(),主任务等待的位置

两种应用场景

  • 让 主任务 等待 所有子任务执行完毕后,再继续执行
  • 让所有子任务同时执行,打印开始时间
    • (扩展)模拟百米冲刺

实现代码

应用一:让 主任务 等待 所有子任务执行完毕后,再继续执行

import java.util.Random;
import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest01 {

    public static void main(String[] args) throws InterruptedException {
        // 定义子任务的个数
        int count = 3;
        // 主任务 latch
        CountDownLatch latch = new CountDownLatch(count);
        // 主任务开始
        System.out.println("主任务开始...");

        Random random = new Random();
        // 三个子任务执行,执行完通知 主任务
        for (int i = 0; i < count; i++) {
            new Thread(() -> {
                // 子线程执行业务,使用随机数模拟执行时间长短
                try {
                    int num = random.nextInt(8);
                    Thread.sleep(num * 1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                // 子任务执行完毕
                System.out.println( "  " + Thread.currentThread().getName() + " 子线程执行任务完毕");
                // 执行完毕通知主任务
                latch.countDown();
            }).start();
        }

        // 主任务等待子任务全部执行完毕
        latch.await();

        // 主任务继续 业务
        System.out.println("全部子任务执行完毕,主任务继续...");
        Thread.sleep(3000);

        // 主任务执行完毕
        System.out.println("主任务执行完毕");
    }

}

执行结果

在这里插入图片描述

应用二:让所有子任务同时执行,打印出发时间

import java.util.Random;
import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest02 {

    public static void main(String[] args) throws InterruptedException {
        // 定义子任务的个数
        int count = 3;

        // 开始信号 latch
        CountDownLatch latch = new CountDownLatch(1);

        for (int i = 0; i < count; i++) {
            new Thread(() -> {
                try {
                    // 等待开始信号
                    latch.await();

                    // 打印出发时间
                    System.out.println(Thread.currentThread().getName() + " 线程出发时间 " + System.currentTimeMillis());

                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }).start();
        }

        // 3 秒后开始
        System.out.println("3 秒后开始...");
        Thread.sleep(3000);
        latch.countDown();
    }

}

执行结果

在这里插入图片描述

应用二(扩展):让所有子任务同时执行,模拟百米冲刺

import java.util.Random;
import java.util.concurrent.CountDownLatch;
/**
 * 应用二:
 *      让所有子任务同时执行,模拟百米冲刺
 *          用一个共享 CountDownLatch(1) order 模拟发令枪,
 *          用一个共享 CountDownLatch(n) answer 模拟n个运动员,
 *          多个运动员在开始执行任务前首先 order.await() 集合,等待 order 1=>0 开始执行
 *
 */
public class CountDownLatchTest03 {

    public static void main(String[] args) throws InterruptedException {
        // 定义运动员的人数
        int count = 3;

        // 发令枪,当从 1 到 0,所有 运动员出发
        CountDownLatch order = new CountDownLatch(1);
        // 运动员
        CountDownLatch answer = new CountDownLatch(count);

        Random random = new Random();
        for (int i = 0; i < count; i++) {
            new Thread(() -> {
                try {
                    // 每个线程是一个运动员,等待 发令枪 从 1 到 0
                    order.await();

                    // 运动员出发
                    System.out.println("  " + Thread.currentThread().getName() + " 运动员出发...");

                    // 使用随机数模拟跑步用时时间长短
                    int num = random.nextInt(8);
                    Thread.sleep(num * 1000);
                    System.out.println( "  " + Thread.currentThread().getName() + " 运动员到达终点,用时 " + num + " s");

                    // 执行完毕到 终点 报道,统计成绩
                    answer.countDown();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }).start();
        }

        // 发布 口令
        System.out.printf("口令:预备 -> 跑\n");
        order.countDown();

        // 等待所有运动员到 终点
        answer.await();

        System.out.println("所有运动员已到终点");
    }

}

执行结果

在这里插入图片描述

  • 23
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值