CountDownLatch应用场景代码练习

news2024/11/27 18:01:39

目录

    • 概念原理
    • 核心参数和方法
    • 两种应用场景
    • 实现代码
      • 应用一:让 主任务 等待 所有子任务执行完毕后,再继续执行
      • 执行结果
      • 应用二:让所有子任务同时执行,打印出发时间
      • 执行结果
      • 应用二(扩展):让所有子任务同时执行,模拟百米冲刺
      • 执行结果

概念原理

  • 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("所有运动员已到终点");
    }

}

执行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1659495.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React:Router-2. createBrowserRouter函数式

参考文档&#xff1a;ReactRouter官网 前边的文章 BrowserRouter组件式路由 提供了组件式路由的方式&#xff0c;在react-router6.4.0及以上版本&#xff0c;提供了 createBrowserRouter 函数式路由创建方式。 一、创建路由 1. 新建router.js文件&#xff0c;使用createBrow…

WPF容器控件之dockpanel、布局控件

dockpanel 容器控件&#xff0c;对其子元素进行或者水平垂直排布&#xff0c;也可以叫停靠面板,也可以让子元素停靠到容器某一个边上&#xff0c;拉伸元素拾起充满全部的高度或者宽度&#xff0c;也可以使最后一个子元素是否铺满剩余的空间。 参数 LastChildFill最后一个子元素…

引用数据类型 栈内存 堆内存

let m { a: 10, b: 20 }; let n m; n.a 15; console.log(m.a) // 15 原因&#xff1a;基本数据类型存储在栈内存中&#xff0c;引用数据类型存储在堆内存中 &#xff0c;引用数据类型存储在堆内存中会在栈内存中创建一个指针&#xff0c;栈内存中的这个指针指向堆内存中的地…

二.Django--创建多个APP路由映射

目录 1-创建项目 2-创建多个APP 3-注册APP 4-创建"前端页面"并做路由映射 各个APP里面的views.py写视图函数等等 1-创建项目 django-admin startproject 项目名 django-admin startproject my_project 2-创建多个APP python manage.py startapp app名 pyth…

遥控挖掘机之ESP8266调试心得(1)

ESP8266调试心得 1. 前言2.遇到的问题2.1 ESP8266模块建立TCP连接时候报错2.2 指令异常问题 3. 更新ESP8266固件3. ESP8266的部分AT指令3. 连接步骤3.1 模块与电脑连接3.2.1 电脑上的设置3.2.2 ESP8266模块作为客户机&#xff08;TCP Cilent&#xff09;的设置步骤 3.2 模块与模…

云计算:数据时代的魔法城堡

云端初探&#xff1a;定义与起源 想象一下&#xff0c;有一个巨大的、无形的仓库&#xff0c;里面存放着全世界的信息与计算能力&#xff0c;你可以随时随地按需提取&#xff0c;无需关心它的物理位置或维护细节。这就是云计算——一种基于互联网的计算方式&#xff0c;它通过…

Hive UDTF之explode函数、Lateral View侧视图

Hive UDTF之explode函数 Hive 中的 explode() 函数是一种用于处理数组类型数据的 User-Defined Table-Generating Function (UDTF)。它将数组拆分成多行&#xff0c;每个数组元素对应生成的一行数据。这在处理嵌套数据结构时非常有用&#xff0c;例如处理 JSON 格式的数据。 …

CentOS 自建gitlab仓库:安装相关工具

所需环境 Node 安装项目依赖、项目打包运行Nginx 前端项目部署&#xff08;正向代理、反向代理、负载均衡等&#xff09;Git 自动化部署时 拉取代码使用GitLab 代码仓库GitLab-Runner GitLab的CI/CD执行器 一、安装Node 检测是否已安装 常用node -v 命令检测。 如果已安装&a…

web前端学习笔记9

9. HTML5新增元素及属性 9.1 HTML5新增结构元素 HTML5引入了几个新的结构元素,极大地改善了网页的组织和结构方式。以下是HTML5中的一些关键新结构元素: 标签说明<header>页面或页面中某一个区块的页眉,通常是一些引导和导航信息<nav>可以作为页面导航的链接组&…

C# WinForm —— 12 ListBox绑定数据

ListBox加载大量数据时&#xff0c;避免窗体闪烁的方法&#xff1a; 在加载语句的前后分别加上 BeginUpdate()方法 和 EndUpdate()方法 指定一个集合为绑定的数据源 1. 首先&#xff0c;右键项目&#xff0c;添加类 2. 在新建的类文件中添加属性值信息 3. 构建初始化的对象…

算法设计课第五周(贪心法实现活动选择问题)

目录 一、【实验目的】 二、【实验内容】 三、实验源代码 一、【实验目的】 &#xff08;1&#xff09;熟悉贪心法的设计思想 &#xff08;2&#xff09;理解贪心法的最优解与正确性证明之间的关系 &#xff08;3&#xff09;比较活动选择的各种“贪心”策略&#xff0c;…

CSP-j 2022csp-j完善程序易错题

易错题 答案23&#xff1a; 对 解析23&#xff1a; 函数 g 就是把函数 f 改成递推的形式 答案24&#xff1a; 对 解析23&#xff1a; 无。 答案25&#xff1a; C 解析25&#xff1a; m n ( m - 1 ) * ( 1 2 3 4 ... n ) O(mn^2) 答案26&#xff1a; C 解析26&#x…

软件设计师笔记(二)-零碎要点

本文内容来自笔者学习zst 留下的笔记&#xff0c;都是零碎的要点&#xff0c;查缺补漏&#xff0c;若有错误请大家提出&#xff0c;希望大家都能通过&#xff0c;记得加上免费的关注&#xff01;谢谢&#xff01; 目录 1. 算法 [广度和深度优先] 2. 遍历方式 3. 四大算法 …

RuoYi-Vue-Plus (Echarts 图表)

一、echarts 图表介绍和使用 官网地址:目前echarts以及贡献给Apache Apache EChartshttps://echarts.apache.org/zh/index.htmlecharts配置项手册 Documentation - Apache EChartshttps://echarts.apache.org/z

第19讲:Ceph集群CrushMap规则定制与调优:从基础到高级应用

文章目录 1.CrushMap规则拓扑结构1.1.集群默认的CrushMap规则拓补图1.2.自定义的CrushMap规则拓补图 2.定制CrushMap规则的方法以及注意事项3.通过二进制文件编写一套CrushMap规则3.1.将系统默认的CrushMap规则导出3.2.根据需求编写CrushMap规则3.3.将编写好的规则导入到集群中…

简单粗暴的翻译英文pdf

背景&#xff1a;看书的时候经常遇到英文pdf&#xff0c;没有合适的翻译软件可以快速翻译全书。这里提供一个解决方案。 Step 1 打开英文pdfCTRLA全选文字CTRLC复制打开记事本CTRLV复制保存为data.txt Step 2 写一个C脚本 // ToolPdf2Html.cpp : 此文件包含 "main&quo…

AJAX家政系统源码部署/售后更新/搭建/上线维护

基于FastAdmin和原生微信小程序开发的一款同城预约、上门服务、到店核销家政系统&#xff0c;用户端、服务端(高级授权)、门店端(高级授权)各端相互依赖又相互独立&#xff0c;支持选择项目、选择服务人员、选择门店多种下单方式&#xff0c;支持上门服务和到店核销两种服务方式…

如何安装ElasticSearch及相关件

一、简介 ElasticSearch是什么&#xff1f; elasticsearch简写es&#xff0c;es是一个高扩展、开源的全文检索和分析引擎&#xff0c;它可以准实时地快速存储、搜索、分析海量的数据。 ElasticSearch 插件 elasticsearch-head是一款专门针对于elasticsearch的客户端工具&am…

Gitee 码云与Git 交互

优质博文&#xff1a;IT-BLOG-CN 一、进入码云官方网站&#xff0c;注册用户 码云(Gitee.com)是一个类似于GitHub的在线代码托管平台。 码云提供了包括版本控制、代码托管、协作开发和代码分享等功能&#xff0c;基于Git开发&#xff0c;支持代码在线查看、历史版本查看、Fo…

什么是分库分表?代表性框架有哪些?

在互联网系统开发过程中&#xff0c;所谓的分库分表并不是一个新概念。或者说&#xff0c;对于很多开发人员而言&#xff0c;说起分库分表&#xff0c;大家都或多或少有所了解&#xff0c;也都知道数据量大了就需要进行分库分表。但是究竟如何实现分库分表呢&#xff1f; 要想…