Java中CountDownLatch的用法

学技术学英文:java CyclicBarrier 和 CountDownLatch用法区别,举例生动看完不会忘 CyclicBarrier 和CountDownLatch 都是java中让线程阻塞等待的,CountDownLatch是父线程等待,CyclicBarrier是子线程等待。 阅读详情

CountDownLatch位于java.util.concurrent包下,是JDK1.5的并发包下的新特性。

首先根据Oracle的官方文档看看CountDownLatch的定义:

A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

 

简单来说,CountDownLatch是一个同步的辅助类,允许一个或多个线程一直等待,直到其它线程完成它们的操作。

这里就涉及两个问题:

1.如何让一个或多个线程一直等待;

2.如何让这些线程知道其它线程已经完成它们的操作

 

这两个问题主要是使用一个count的属性解决。使用count初始化CountDownLatch,然后需要等待的线程调用await方法。await方法会一直受阻塞直到count=0。

而其它线程完成自己的操作后,调用countDown()使计数器count减1。当count减到0时,所有在等待的线程均会被释放,并且count无法被重置。如果需要重置,请参考CyclicBarrier 

 

假设有以下的场景,3个学生做试卷考试,老师要等所有学生做完试卷后才收卷。具体代码如下:

先看学生Student.java:

复制代码
 1 import java.util.Random;
 2 import java.util.concurrent.CountDownLatch;
 3 import java.util.concurrent.TimeUnit;
 4 
 5 public class Student implements Runnable {
 6     
 7     private int num;
 8     private CountDownLatch cdlatch;
 9     
10     Student(int num,CountDownLatch latch){
11         this.num = num;
12         this.cdlatch = latch;
13     }
14 
15     @Override
16     public void run() {
17         doExam();
18         try {
19             TimeUnit.SECONDS.sleep(new Random().nextInt(10));
20         } catch (InterruptedException e) {
21             // TODO Auto-generated catch block
22             e.printStackTrace();
23         }
24         System.out.println("Student "+num+" finished!");
25         cdlatch.countDown();
26     }
27     
28     private void doExam(){
29         System.out.println("Student "+num+" is doing the exam!");
30     }
31     
32 }
复制代码

 

再看老师Teacher.java:

复制代码
 1 import java.util.concurrent.CountDownLatch;
 2 
 3 public class Teacher implements Runnable{
 4     
 5     private CountDownLatch cdlatch;
 6     
 7     Teacher(CountDownLatch latch){
 8         this.cdlatch = latch;
 9     }
10     
11     @Override
12     public void run() {
13         // TODO Auto-generated method stub
14         try {
15             System.out.println("teacher is waiting...");
16             cdlatch.await();
17             System.out.println("teacher is collecting......");
18         } catch (InterruptedException e) {
19             // TODO Auto-generated catch block
20             e.printStackTrace();
21         }
22     }
23 
24 }
复制代码
View Code

 

我们可以看到运行的结果:

teacher is waiting...
Student 101 is doing the exam!
Student 102 is doing the exam!
Student 103 is doing the exam!
Student 102 finished!
Student 101 finished!
Student 103 finished!
teacher is collecting......

 

再来看一个稍微复杂点的例子,10个选手比赛跑步,在枪响后同时起跑,全部到达终点后比赛结束:

复制代码
 1 import java.util.concurrent.CountDownLatch;
 2 import java.util.concurrent.ExecutorService;
 3 import java.util.concurrent.Executors;
 4 
 5 
 6 public class CountDownLatchDemo {
 7 
 8     private static int PLAYER_NUM = 10;
 9     
10     public static void main(String[] args) {
11         
12         final CountDownLatch beginSignal = new CountDownLatch(1);
13         final CountDownLatch endSignal = new CountDownLatch(PLAYER_NUM);
14         
15         ExecutorService executorService = Executors.newFixedThreadPool(PLAYER_NUM);
16         
17         for(int i=0;i<PLAYER_NUM;i++){
18             final int num = i+1;
19             Runnable runner = new Runnable(){
20 
21                 @Override
22                 public void run() {
23                     // TODO Auto-generated method stub
24                     System.out.println("No. "+num+" is waiting...");
25                     try {
26                         beginSignal.await();
27                         System.out.println("No. "+num+" begin running");
28                         Thread.sleep((long) (Math.random() * 10000));
29                         System.out.println("No." + num + " arrived");
30                     } catch (InterruptedException e) {
31                         // TODO Auto-generated catch block
32                         e.printStackTrace();
33                     }finally{
34                         endSignal.countDown();
35                     }
36                 }
37                 
38             };
39             executorService.execute(runner);
40         }
41         
42         System.out.println("before Game Start");
43         beginSignal.countDown();
44         System.out.println("Game Start");
45         System.out.println("---In the middle of the game---");
46         try {
47             endSignal.await();
48         } catch (InterruptedException e) {
49             // TODO Auto-generated catch block
50             e.printStackTrace();
51         }finally{
52             System.out.println("Game Over!");
53             executorService.shutdown();
54         }
55 
56     }
57 
58 }
复制代码

 

以上逻辑不难理解,beginSignal的count=0时,runner线程开始运行,直到endSignal的count=0时结束。

接下来分析一下运行6次的结果:

 

可以看到,因为有beginSignal,所以可以保证所有runner都waiting以后,才begin running。同理,因为有endSignal,可以保证所有runner arrived后才Game Over!

但是,这里的需要留意主线程的几个输出:

1 System.out.println("before Game Start");
2 beginSignal.countDown();
3 System.out.println("Game Start");
4 System.out.println("---In the middle of the game---");

1.尽管before Game Start在countDown()之前,但不能保证is waiting全部输出完后,才输出before Game Start。

2.“Game Start”和"In the middlel of the game"虽然都在countDown()之后,但在多线程的环境下(主线程也是线程之一),无法预计两个字段输出的位置。从上面的case看,有可能在running的前面,中间和后面,无法预计。这里要十分注意。

3.因为有Thread.sleep,所以arrived都在running之后出现。否则,arrived出现的位置,就不一定都在running之后了。

 

对于第一点,其实还没想明白,为什么顺序是No.9 is waiting --> before Game Start --> No.10 is waiting 而不是 No.9 is waiting --> No.10 is waiting --> before Game Start?

【Java 多线程 6】countdownlatch用法 一、CountDownLatch简介 CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。 CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成一些任务,然后在CountDownLatch上等待的线程就可以恢复执行接下来的任务。 二、CountDownL 阅读详情

相关推荐

java CountDownLatch、CyclicBarrier和 Semaphore用法

一.CountDownLatch用法   CountDownLatch类位于java.util.concurrent中包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。   CountDownLatch类只提供了一个构造器: public CountDownLatch(int cou...

gmHappy 6572

Java并发——CountDownLatch

`CountDownLatch`是Java并发中常用的一个工具类,通常称为锁存器latch,作用为同步一个或多个任务,强制等待指定任务执行完成,即多线程中控制一个或多个线程去等待其他线程完成操作。本文将详解介绍CountDownLatch的使用及底层原理。

雪月清的博客 1947

MATLAB控制信号发生器(USB-GPIB-HS)GPIB仪器控制教程(含matlab代码)

自动化测试时需要自动产生信号,通过matlab控制信号发生器的频率与功率,以实现自动化信号生成输出

qq_43686057的博客 1606

CountDownLatch介绍和使用【Java多线程必备】

CountDownLatch介绍、特性、注意事项、使用案例(干货满满)

Mr.绵羊的知识星球 3万+

QMT中ContextInfo的使用注意

QMT中ContextInfo下声明的全局变量的使用注意事项

路在何方 2807

【DICOM后处理】qt+vs 实现DICOM数据四视图显示

方法用于 设置 2D 视图的“向上”方向,即定义图像在屏幕坐标系中的朝向。该方法直接影响影像的显示方向,尤其在多平面重建(MPR)或非标准切面显示时至关重要。:方法用于 设置渲染窗口在屏幕上的显示位置(以像素为单位)。它控制的是 VTK 渲染窗口的左上角在屏幕坐标系中的坐标位置。DICOM四视图通常指同时显示医学影像的四个不同平面或视角,用于全面分析三维数据(如CT、MRI等)。:基于 标量值 设置不透明度(控制不同组织的显示),显示骨骼or显示高密度流体等。默认朝向原点 (0, 0, 0)

weixin_41804847的博客 1325

Java CountDownLatch 学习总结

同为 java.util.concurrent 下的,即也是并发多线程相关下的类,直译 “倒计时锁存器”,一般用于多线程场景,单一的线程也可以,用于等待多个任务完成后再执行其他操作;就是当使用了这个方法后当前这一个线程将进入等待状态,直到计数器被减到0或者当前线程被中断,计数器被减到0后,所有等待的线程将被唤醒继续向下执行。同上,但是指定了等待的超时时间,即线程除了上方两种被唤醒的情况下,等待到超时时间后也会被唤醒。则抛出{@link InterruptedException},并清除当前线程的中断状态。.

weixin_44131922的博客 1527

Palantir Vertex:数字孪生模拟与决策系统深度指南

Palantir Vertex是Foundry系统中的核心数字孪生模块,本质上是一个决策模拟器而非简单的数据可视化工具。它基于本体层构建,通过对象关系网络模拟现实世界实体,填补数据模型与业务决策间的鸿沟。核心功能包括:创建隔离的沙盒场景进行假设测试、修改参数模拟不同干预方案、对比虚实数据发现异常,并最终将最优决策回传至业务系统。典型应用场景涵盖供应链韧性评估、资产维护优化和应急方案制定等,帮助用户在复杂环境中做出更优决策。

轩哥的个人研究和成长记录 891

Java 多线程之 CountDownLatch(计数等待/同步辅助类)

CountDownLatch 是Java中提供的一种同步工具类,用于控制多个线程之间的执行顺序和协调。CountDownLatch 通过一个计数器来实现,该计数器初始化为一个正整数,表示需要等待的线程数目。每个线程执行完一定的任务后,会调用方法将计数器减1。当计数器减到0时,表示所有线程已经完成任务,等待在await()方法处的线程被唤醒,继续执行后续操作。控制执行顺序:控制多个线程执行的顺序,让某个线程等待其他线程完成特定任务后再执行。

QIFU的专栏 2114

Kindle电子书DRM破解全攻略:从下载到转换的完整流程(含最新DeDRM插件配置)

本文详细介绍了如何合法移除个人购买的Kindle电子书的DRM保护,实现跨设备阅读与备份。核心内容包括使用最新DeDRM插件(如noDRM分支)配合Calibre进行配置,并针对亚马逊最新的KFX加密格式提供了密钥提取与实战操作指南。文章强调该方法仅适用于个人合理使用,旨在帮助读者真正掌控自己的数字资产。

delta的博客 576

uniapp(vue3)- 详解安装/使用pinia报错reportJSException >>>> exception function:createInstanceContext, excepti

uniapp vue3 pinia报错reportJSException >>>> exception function:createInstanceContext, exception:white screen cause create instanceContext failed,check js stack -> at useStore,H5网页,微信小程序,安卓App,苹果App,nvue,uniapp安装使用pinia出现报错at useStore,uniapp+vue3+ts 使用pinia报

🏆 前端领域优质创作者 4047

[Java]CountDownLatch类的使用

CountDownLatch是用来同步多个线程的执行顺序的,如果有多个线程在执行,有任务需要等这几个线程都执行完了再执行,此时可以在这个任务前面将这几个前驱线程的所有join都调用一遍,但是如果线程的数目越来越多,join也越来越多,这显然增加了编程的繁琐程度也容易出错。注意:有序countDown方法可以放在线程run方法的任意位置,其实后续任务不一定是要前驱贤臣都执行结束才继续执行,也可能前驱任务执行了一部分就可以执行了。countDown和await方法配合使用才能达到等待前驱线程完成的效果。

qq_61925446的博客 321

19、硬件工程师笔试面试——无线通讯模块(2025版本)

例如,如果你的项目需要传输大量数据,如视频流或大数据文件,那么你可能需要一个高速率的模块,如支持802.11ac或802.11ax(WiFi 6)的模块。如果你的数据传输需求较小,如传感器数据,那么一个较低速率的模块,如蓝牙或Zigbee,可能就足够了。较高的频率(如5GHz)提供更大的带宽,支持更高的数据传输速率,但信号覆盖范围较小,穿透能力较弱。例如,在蓝牙通信中,一台设备作为主机,另一台设备作为从机,它们通过频率跳频的方式确定连接,并在连接建立后通过特定的协议进行数据交换。

XU157303764的博客 3226

java CountDownLatch用法简介

CountDownLatch:用于协同控制一个或多个线程等待在其他线程中执行的一组操作完成,然后再继续执行。ps:CountDownLatch注意事项:只可使用一次,不能重复使用,计数变为0之后,就不可再用。1.需要一个totalCount指定等待的条件数(任务数、操作数)2.需要一个countDown计算有几个线程 结束了。

weixin_46102873的博客 560

功能安全实战系列12-英飞凌TC3xx锁步核及其自检开发

本文介绍了英飞凌Tricore系列芯片的锁步核(Lockstep Core)功能及其故障注入自检机制。锁步核通过主核和检查核同步执行指令,并比较输出结果来检测硬件故障。文章详细阐述了锁步核的工作原理、使能配置方法以及故障注入自检的实现过程。故障注入测试通过专用寄存器LCLTEST触发,系统会定期自动测试比较器节点,验证锁步核的故障检测能力。当检测到异常时,会触发SMU模块的警报机制。该技术为汽车电子系统提供了重要的功能安全保障。

initiallizer的博客 920

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Java 中 CountDownLatch 的基本用法

Java 中 CountDownLatch 的基本用法

JonTang的博客 1242

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

java并发包CountDownLatch的用法

public static void main(String[] args) { // countDownLatch初始化 ,其功能类似于计数器。。 /*常见的应用场景: 某个线程必须等待其他的线程执行完毕之后才执行; * * 例如: 主线程,必须等待其他两个线程执行完毕才开始执行(代码如下) * **/ CountDownLatch countDownLat...

fank 359

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

浅析Java中CountDownLatch用法

学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:183993990 我们一起学Java! ...

chuifuhuo6864的博客 212

java CountDownLatch类的用法

CountDownLatch类中维护了一个计数器,当计数器为0时,释放所有线程。这个类可以用于当所有的资源都初始化后进行操作。 CountDownLatch中的await方法等待计数器达到0,表示所有的线程已经执行完毕。如果计数器不为0,await()方法会一直阻塞等待计数器变为0。而countDown()方法用于递减计数器。 下面是一个计算执行时间的例子: [code="jav...

一木一草一枯荣 203

java中CountDownLatch的用法

每次有线程调用 countDown()数量-1,假设计数器变为0,countDownLatch.await() 就会被唤醒,继续执行。等待计数器归零,然后再向下执行countDownLatch.await();countDownLatch.countDown() 数量-1。

m0_61366135的博客 425

Java CountDownLatch用法

CountDownLatch用于阻塞一个线程,等待其它线程先后到达某个条件的时候,再执行这个线程的后续操作。 public class CountDownLatchTest { public static void main(String[] args) throws InterruptedException { new CountDownLatchTest().go(...

Eddie-Wang的博客 274

java并发包下CountDownLatch、Semaphore用法

java并发包下CountDownLatch用法

lixiaobai_boke的博客 243

java CountDownLatch的用法

CountDownLatch:让一些线程阻塞直到另外一些线程完成后才被唤醒。CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞,其他线程调用countDown方法计数器减1(调用countDown方法时线程不会阻塞),当计数器的值变为0,因调用await方法被阻塞的线程会被唤醒,继续执行 场景:假设我们现在教室里面一共有6个人,分别为5个学生...

Zhang895341748的专栏 377

请解释Java中的CountDownLatch、CyclicBarrier和Semaphore的用法?

在Java的并发编程中,CountDownLatch、CyclicBarrier和Semaphore都是重要的同步工具类,它们各自用于不同的场景,帮助协调多个线程的执行顺序。它维护了一个计数器,当计数器的值减至0时,表示一组线程中的最后一个线程已经完成了任务,此时等待的线程将不再阻塞,可以继续执行。在需要等待的线程中调用CountDownLatch的await()方法,该方法会阻塞当前线程,直到计数器的值减至0。在每个线程中,当需要等待其他线程时,调用CyclicBarrier的await()方法。

weixin_53180424的博客 976

Java-CountDownLatch的用法

CountDownLatch也属于JUC。线程可以使用await()进行等待,多线程进行递减计数,等到计数到0的时候等待即不再阻塞,从而向下执行。 在日常开发中经常会遇到需要在主线程中开启多个线程去并行执行任务,并且主线程需要等待所有子线程执行完毕后再进行汇总的场景。

ksidgx的博客 969

JAVA concurrent包下Semaphore、CountDownLatch等用法

JAVA concurrent包下Semaphore、CountDownLatch等用法 CountDownLatch 跟join的区别 CountDownLatch用处跟join很像,但是CountDownLatch更加灵活,如果子线程有多个阶段a、b、c; 那么我们可以实现在a阶段完成后(在a阶段后 ,b、c阶段之前, latch.co...

weixin_30879833的博客 107
上一篇: Java CyclicBarrier的用法
下一篇: 【推荐】基于zookeeper简单实现分布式锁
大树叶
博客等级 码龄12年 1171粉丝 664原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值