Java多线程拾遗(五) 使用CountDownLatch同步线程
CountDownLatch 是什么?
先看看CountDownLatch源码注释第一行给出的定义。
让一个或多个线程等待,直到在其他线程中执行的一组操作完成的同步辅助程序
我们在编码中很多时候需要多线程来提高效率,而有时候我们需要让一个或一些线程完成一些任务后,再继续向下执行代码,而CountDownLatch作为一个同步工具类,能够满足这样的需求。
CountDownLatch能够使一个线程在等待另外一些线程都完成各自工作
之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成一些任务,然后在CountDownLatch上等待的线程就可以恢复执行接下来的任务。
CountDownLatch的用法
该类下的方法并不多。
构造函数
参数为int类型,即计数器的"初始数"
public CountDownLatch(int count) {if (count < 0) throw new IllegalArgumentException("count < 0");this.sync = new Sync(count);}
await()
该方法可以让当前线程阻塞,直到计数器的"初始数"变为0
public void await() throws InterruptedException {sync.acquireSharedInterruptibly(1);}
下面这个方法为await的重写,timeout为超时时间,第二个为时间单位。
public boolean await(long timeout, TimeUnit unit)throws InterruptedException {return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));}
countDown方法
让计数器的数减一
public void countDown() {sync.releaseShared(1);}
getCount()
获取当前计数器的数值。
public long getCount() {return sync.getCount();}
toString()
便于输出而重写的toString方法
public String toString() {return super.toString() + "[Count = " + sync.getCount() + "]";}
CountDownLatch典型场景:
1、某一线程在开始运行前等待n个线程执行完毕。
将CountDownLatch的计数器初始化,new CountDownLatch(n)。
每当一个任务线程执行完毕,就通过countDown()
方法将计数器减1 ,当计数器的值变为0时,在CountDownLatch上await()的线程就会被唤醒。
一个典型应用场景就是启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行。
/*** @author 阳光大男孩!!!*/
public class CountDownLatchDemo {public static void main(String[] args) throws InterruptedException {// 初始计数为5CountDownLatch countDownLatch = new CountDownLatch(5);for (int i = 0; i < 5 ; i++) {new Thread(() -> {System.out.println(Thread.currentThread().getName()+"执行任务...");System.out.println(Thread.currentThread().getName()+"执行完毕");// 执行完毕,计数器-1countDownLatch.countDown();},String.valueOf(i)).start();}// 阻塞,直到计数器为0countDownLatch.await();System.out.println("可算执行完了...");}
}
可以看到,当所有的线程完成各自的工作时,await()方法才会停止阻塞,继续向下执行。
2、实现多个线程开始执行任务的最大并行性。注意是并行性,不是并发,强调的是多个线程在某一时刻同时开始执行。类似于赛跑,将多个线程放到起点,等待发令枪响,然后同时开跑。
做法是初始化一个共享的CountDownLatch(1),将其计算器初始化为1,多个线程在开始执行任务前首先countdownlatch.await(),当主线程调用countDown()时,计数器变为0,这里的主线程就是发令枪,多个线程同时被唤醒。
CountDownLatch的不足
从前面方法的分析中可以看出,由于计算器的值只能在构造方法中初始化一次,所以CountDownLatch是一次性的,之后没有任何机制再次对其设置值,当CountDownLatch使用完毕后,它不能再次被使用。
参考博客
https://www.cnblogs.com/Lee_xy_z/p/10470181.html
Java多线程拾遗(五) 使用CountDownLatch同步线程相关推荐
- 详解Java多线程编程中LockSupport类的线程阻塞用法
转载自 详解Java多线程编程中LockSupport类的线程阻塞用法 LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了基本的线程同步原语.LockSupport实际 ...
- Java多线程系列(五):线程池的实现原理、优点与风险、以及四种线程池实现
为什么需要线程池 我们有两种常见的创建线程的方法,一种是继承Thread类,一种是实现Runnable的接口,Thread类其实也是实现了Runnable接口.但是我们创建这两种线程在运行结束后都会被 ...
- Java 多线程详解(三)------线程的同步
Java 多线程详解(一)------概念的引入:https://blog.csdn.net/weixin_39816740/article/details/80089790 Java 多线程详解(二 ...
- Java多线程系列(九):CountDownLatch、Semaphore等4大并发工具类详解
之前谈过高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景 ,以及高并发编程系列:ConcurrentHashMap的实现原理(JDK1.7和JDK1.8) 今天主要介绍concurre ...
- java多线程下LongAdder、CountDownLatch、CyclicBarrier、Phaser 的用法
前言 一文读懂java多线程下常用常考的阻塞方法LongAdder.CountDownLatch.CyclicBarrier.Phaser 包含演示代码 高并发模拟,性能比较实例代码 前言 LongA ...
- java多线程基础学习[狂神说java-多线程笔记]
java多线程基础学习 一.线程简介 1.类比 2.程序进程线程 3.线程的核心概念 二.线程的实现(重点) 调用方法与调用多线程的区别 Thread 类 1.thread使用方法 2. 代码实现 3 ...
- java多线程为啥一直用的一个线程_一个Java多线程的问题,颠覆了我多年的认知!...
作者 | ithuangqing 来源 | 编码之外(ID:ithuangqing) 碰见个奇怪的多线程问题 小白们也不用怕,今天的文章你们都能看得懂,最近的学习中,碰到这样的一个问题: Java创建 ...
- Java多线程技能(九)——暂停线程
目录 1.suspend与resume方法的使用 2.suspend与resume方法的缺点--独占 3.suspend与resume方法的缺点--不同步 暂停线程意味着此线程还可以恢复运行.在 ...
- Java多线程001——一图读懂线程与进程
本博客 猫叔的博客,转载请申明出处 前言 本系列将由浅入深,学习Java并发多线程. 一图读懂线程与进程 1.一个进程可以包含一个或多个线程.(其实你经常听到"多线程",没有听过& ...
最新文章
- java 待在原页面 代码_现在java后台,只要修改一点点代码,前段页面就报500,必须重新登录才行?...
- 清理 zabbix 历史数据, 缩减 mysql 空间
- 《研磨设计模式》chap9 原型模式Prototype
- 更改列表的默认项标记的颜色、大小等样式的解决办法
- DM365的BSP源码分析-基于2.6.18内核
- 获取10~99(包含10和99)的“总和”与“偶数”的个数
- [零基础学JAVA]Java SE应用部分-28.Java IO操作(02)
- gitlab ci php 构建,GitLab CI的入门搭建
- 大数据之-Hadoop之HDFS的API操作_配置参数的优先级说明_以设置hdfs文件副本数量参数为案例---大数据之hadoop工作笔记0057
- C# await和async
- EXCEL复制可见单元格
- 如何成为高手?嵌入式开发进阶之路...
- 实验吧ctf题库:这个看起来有点简单!
- CMD命令行高级教程精选合编合集
- Word【内容一键生成目录】
- 第四届江西省高校网络安全技能大赛 复现 2021-09-30
- GD32F303固件库开发(7)----printf打印配置
- LTE PDCP层协议概述
- python安装advanced options_python 安装配置(windows)
- 【第三方互联】9、新浪微博(sina)授权第三方登录
热门文章
- ArcSDE10.2 连接PostSql9.2的安装与配置(含10.2全套下载链接)
- linux怎么用终端关闭wps,硬核关闭wps for linux的自动备份功能
- YTU 2901: G-险恶逃生II
- CF-Edu101-D-Ceil Divisions(构造)
- 不清晰的图片怎么一键变清晰?分享几个简单好用的AI图片变清晰工具
- Au:CdTe量子点标记人肺癌细胞A549细胞|红色荧光水溶性InP/ZnS量子点(磷化铟/硫化锌)PEG氨基
- QFileDialog界面英文显示
- 抖音小程序CPS推广变现系统开发
- MFC:如何利用C++使得输出文本颜色、字体多变
- 百度违禁词查询过滤工具