CountDownLatch类的使用

news2024/11/16 20:34:23

🎈专栏链接:多线程相关知识详解

目录

一.CountDownLatch的介绍

二.CountDownLatch类里面的方法

三.CountDownLatch的两种应用场景

①一等多情况

②多等一情况


一.CountDownLatch的介绍

CountDownLatch是一种用来控制多线程的工具类,它被称为门阀、计数器或者闭锁.

二.CountDownLatch类里面的方法

CountDownLatch(int count){...}    类中唯一的构造器,用来构造一个用给定计数初始化的CountDownLatch

await(){...}    调用该方法的线程会阻塞,直到计数器count的值为0的时候才唤醒

countDown(){...}     如果当前计数大于零,则对其递减,当计数为0的时候等待的线程将会被唤醒

getCount(){...}   获得计数器的值,即当前还需要执行完几个线程

三.CountDownLatch的两种应用场景

①一等多情况

例如:老板需要检查工人需要干的活完成的情况如何,但老板得等待所有的工人全部完成工作的时候才去检查,即一等多

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class Worker implements Runnable{
    private CountDownLatch downLatch;
    private String name;

    public Worker(CountDownLatch downLatch,String name){
        this.downLatch = downLatch;
        this.name = name;
    }
    @Override
    public void run() {
        this.doWork();
        try {
            TimeUnit.SECONDS.sleep(new Random().nextInt(10));//随机休息1~10秒的时间
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(this.name + "活干完了!");
        this.downLatch.countDown();//当前线程把计数器减一
        System.out.println("剩余线程的个数: " + downLatch.getCount());
    }

    private void doWork(){
        System.out.println(this.name + "正在干活!");
    }
}

class Boss implements Runnable{
    private CountDownLatch downLatch;
    public Boss(CountDownLatch downLatch){
        this.downLatch = downLatch;
    }
    @Override
    public void run() {
        System.out.println("老板正在等待所有工人干完活...");
        try {
            this.downLatch.await();//使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断,如果计数器为0则此方法立刻返回
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("工人的活都干完了,老板开始检查了!");
    }
}

public class Demo1 {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();//使用线程池
        CountDownLatch latch = new CountDownLatch(3);//设置线程运行次数
        Worker worker1 = new Worker(latch,"张三");
        Worker worker2 = new Worker(latch,"李四");
        Worker worker3 = new Worker(latch,"王五");

        Boss boss = new Boss(latch);

        executor.execute(worker1);
        executor.execute(worker2);
        executor.execute(worker3);
        executor.execute(boss);


        executor.shutdown();//不再接受新的任务
    }
}

运行结果: 

由于线程的抢占式执行,前面的运行结果顺序可能是不一样的,但是老板开始检查一定是在所有的工人完成任务后才会开始执行的

②多等一情况

例如:运动会上的跑步比赛,所有的运动员得先在各自的跑道上等待裁判员的口令,当裁判员的宣布比赛开始的时候跑道上的运动员才能开始比赛.

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Runner implements Runnable{
    private CountDownLatch downLatch;
    private String name;

    public Runner(CountDownLatch downLatch,String name){
        this.downLatch = downLatch;
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(name + "正在等待跑步口令");
        try {
            this.downLatch.await();//等待计数器的值减到0才会往下运行
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(name + "开始跑步!");
    }
}

class Judge implements Runnable{
    private CountDownLatch downLatch;

    public Judge(CountDownLatch downLatch){
        this.downLatch = downLatch;
    }
    @Override
    public void run() {
        System.out.println("裁判员发出口令!");

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        this.downLatch.countDown();//计数器减1
    }
}
public class Demo2 {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();//使用线程池
        CountDownLatch downLatch = new CountDownLatch(1);//因为只有一位且要等裁判员所以初始值为1

        Runner runner1 = new Runner(downLatch,"1号");
        Runner runner2 = new Runner(downLatch,"2号");
        Runner runner3 = new Runner(downLatch,"3号");

        Judge judge = new Judge(downLatch);

        executor.execute(runner1);
        executor.execute(runner2);
        executor.execute(runner3);

        Thread.sleep(3000);//先让上面能执行的先执行完,避免与下面的线程发生抢占式执行

        executor.execute(judge);

        executor.shutdown();//不再接受新的任务
    }
}

运行结果:

为了避免抢占式执行,先让上面的线程能执行的先执行,然后再进行等待下面的线程执行,直到计数器的值变为0,才会开始执行剩下的内容

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

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

相关文章

LeetCode HOT 100 —— 301.删除无效的括号

题目 给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。 返回所有可能的结果。答案可以按 任意顺序 返回。 思路 DFS 回溯算法: 首先最终合法的方案,必然有左括号的数量 右括号的数量 …

钉钉获取免登用户信息

大家好,这里是一口八宝周👏 欢迎来到我的博客❤️一起交流学习 文章中有需要改进的地方请大佬们多多指点 谢谢🙏 最近好像搞了个什么钉钉小程序,具体做什么咱也不知道,就让我搞一个钉钉获取免登录用户信息的接口出来&…

计网理论模拟

一. 单选题(共10 题,20.0分) 1. (单选题,2.0分)网络协议主要由 3 个基本要素组成,即( ) A. 层次、语义和同步B. 语法、原语和同步C. 语法、语义和同步D. 语法、语义和功能 正确答案: C 2. (单选题,2.0分…

计算机毕业设计ssm+vue基本微信小程序的智能图书管理系统

项目介绍 本设计旨在研究一种社区图书管理系统设计与实现系统,以各种浏览器web页面加上云服务器后端服务系统,通过这一设计过程,进一步熟悉web前端开发技术和云服务器后端开发技术和方法,培养理论联系实际及知识的综合运用能力。 图书管理系统可以有效实现图书管理的规范化、系…

SAP Gateway 后台模型的缓存设置

/iwbep/cl_mgw_med_provider 类里的成员 mv_cache_active: 这个 cache 默认是开启状态。 调用 OData 服务的 MPC_EXT 类的 get_last_modified 方法获取最后一次修改的时间戳。这个时间戳(timestamp)也会影响到 cache 的行为,我们后续也会详细讨论。 第12 行 super 方…

PySpark--spark local 的环境部署

Spark环境搭建-Local 环境搭建 基本原理 本质:启动一个JVM Process进程(一个进程里面有多个线程),执行任务Task Local模式可以限制模拟Spark集群环境的线程数量, 即Local[N] 或 Local[*]其中N代表可以使用N个线程,每个线程拥有一个cpu core。…

【使用Netty实现群发消息】

使用Netty实现群发消息netty简单介绍实现群发流程图代码实现NettyServer 类MyChannelInitializer 类MyServerHandler 类ChannelHandler 类Netty 依赖效果展示netAssist 工具启动Netty server打开netAssist 工具netty简单介绍 Netty是由JBOSS提供的一个java开源框架&#xff0c…

第三十一章 linux-模块的加载过程

第三十一章 linux-模块的加载过程 文章目录第三十一章 linux-模块的加载过程sys_init_modulestruct moduleload_module在用户空间,用insmod这样的命令来向内核空间安装一个内核模块,本节将详细讨论模块加载时的内核行为。当调用“insmod demodev.ko”来安…

通讯录的思路与实现(C语言)

目录 前言 程序的分装 程序的结构 函数实现 通讯录的初始化 通讯录的扩容 将数据保存到本地 增加联系人 显示通讯录所有联系人 目标联系人的检索(根据名称) 目标联系人的检索(根据号码) 检索发展来的函数 删除联系人 查询目标联系人 联系人信息的更改 按名称对通…

Python写个“点球大战”小游戏

大家好,欢迎来到 Crossin的编程教室 ! 看过我Python入门教程的朋友应该会看到其中有提到一个点球小游戏的作业。 在世界杯决赛即将到来之际,我们再来回顾一下这个小游戏。对于刚刚学习编程不久的同学,这是个不错的练手习题&…

(二)RT-Thread入门——线程管理

目录 线程管理 线程管理特点 线程工作机制 线程控制块 线程属性 线程栈 线程状态 线程优先级 时间片 线程入口函数 无限循环模式 顺序执行或有限次循环模式 线程错误码 线程状态切换 线程操作 创建动态线程 删除 初始化静态线程 脱离 获得当前线程 让出…

数据结构基础篇》》用c语言实现复数的八个基本运算

数据结构开讲啦!!!🎈🎈🎈 本专栏包括: 抽象数据类型线性表及其应用栈和队列及其应用串及其应用数组和广义表树、图及其应用存储管理、查找和排序将从简单的抽象数据类型出发,深入浅出…

B-013 缓启动电路设计

缓启动电路设计1 简介2 案例分析2.1 电路说明2.2 原理分析3 电路参数设定说明1 简介 缓启电路的供电是由一个PMOS控制通断的,软启动的设计是让PMOS的导通时间变缓,电路上的做法是在PMOS的栅极和源极之间接一个合适的电容,PMOS的导通时间就会…

Arcgis中创建Python脚本工具

文章目录创建工具步骤第一步:第二步:第三步:定义工具工具箱Toolbox工具类1、__init__2、getParameterInfo3、isLicensed4、updateParameters5、updateMessage6、execute进度条的使用代码相比于自定义工具箱的源脚本和参数定义难以集中管理的缺…

中国专利电子申请网站系统环境配置方法

一、在线平台使用环境要求 支持的操作系统、浏览器、office的版本如下,必须匹配对应的版本: 操作系统:WINDOWS XP、WINDOWS 7、WINDOWS 8 浏览器:IE8、IE9、IE10 文档编辑软件:OFFICE2003、OFFICE2007 强烈推荐使用中…

1. Maven基础

1. Maven简介 Maven是专门用于管理和构建Java项目的工具,它的主要功能有: 提供了一套标准化的项目结构 提供了一套标准化的构建流程(编译,测试,打包,发布……) 提供了一套依赖管理机制 1.1…

Allegro快速编辑丝印文字操作指导

Allegro快速编辑丝印文字操作指导 Allegro支持丝印文字的编辑,下面介绍快速编辑丝印文字的两种方法如下 以编辑下方丝印文字为例 方法一: 选择Text edit 命令 点击丝印文字,丝印会被高亮起来 输入需要更改后的文字,如下 右击选择done 文字被更改好了 方法二 选择se…

Function composition

In mathematics, function composition is an operation  ∘  that takes two functions f and g, and produces a function h g  ∘  f such that h(x) g(f(x)). In this operation, the function g is applied to the result of applying the function f to x. That is…

van-uplaoder保存文件到后端,回显后端接口返回的数据

实现功能:在移动端使用van-uploader组件上传图片,然后调用接口保存到后端数据库,提交保存信息成功后,调用另外的接口返回数据用来回显uploaded的文件,(一般正常的返回数据的接口是个图片地址,可…