Java中CountDownLatch的使用和求多线程的运行时间
一、CountDownLatch的API
- 构造方法摘要
构造方法
Constructor and Description CountDownLatch(int count)
构造一个以给定计数CountDownLatch
CountDownLatch。
- 方法摘要
所有方法 接口方法 具体的方法
Modifier and Type Method and Description void
await()
导致当前线程等到锁存器计数到零,除非线程是 interrupted 。boolean
await(long timeout, TimeUnit unit)
使当前线程等待直到锁存器计数到零为止,除非线程为 interrupted或指定的等待时间过去。void
countDown()
减少锁存器的计数,如果计数达到零,释放所有等待的线程。long
getCount()
返回当前计数。String
toString()
返回一个标识此锁存器的字符串及其状态。
可以看到 CountDownLatch 类有两个最重要的方法
countDown() 让计数值-1
await() 阻塞线程,直到计数值为0才唤醒
计数值最小为0
通过一个简单的例子可以验证上面的观点,不使用线程即可
测试1
- public static void main(String args[]) throws InterruptedException {
- final CountDownLatch latch = new CountDownLatch(5);//设置计数值为5
- System.out.println("开始你的表演!");
- for(int i=0;i<3;i++) {
- latch.countDown();
- System.out.println("latch.getCount:"+latch.getCount());
- }
- latch.await();
- System.out.println("再见吧,大海!");
- }
运行结果如下
可见,当计数值为2的时候,遇到了 await(),此后将会一直处于等待状态(看左侧的红色按钮,表示程序还在等待)
测试2
- public static void main(String args[]) throws InterruptedException {
- final CountDownLatch latch = new CountDownLatch(5);//设置计数值为5
- System.out.println("开始你的表演!");
- for(int i=0;i<8;i++) {
- latch.countDown();
- System.out.println("latch.getCount:"+latch.getCount());
- }
- latch.await();
- System.out.println("再见吧,大海!");
- }
还是上面的代码,我们把 3 改成一个更大点的数,比如8
运行结果如下
结果说明,当计数值为0时,await()才会继续执行,而不会等待
同时,也发现计数值最小值为 0
二、求多线程的运行时间
CountDownLatch 允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。
这里我们可以实现一个功能,就是 “统计多线程的执行时间”,因为我们需要判断多线程是什么时候 start的,什么时候 end 的。而正好 CountDownLatch 类可以帮助我们知道什么时候结束。
让我们一步步实现它!
1、如何计算某段代码的运行时间
- public static void main(String args[]) {
- long startTime = System.currentTimeMillis();
- for(int i=0;i<1000;i++) {
- System.out.println(i);
- }
- long endTime = System.currentTimeMillis();
- System.out.println((endTime-startTime)+"ms");//13ms
- }
通过 System.currentTimeMillis() 方法获得当前系统时间(单位ms)
下面我们来求多线程的执行时间
2、失败的例子
- public static void main(String args[]) {
- System.out.println("主线程开始");
- long startTime = System.currentTimeMillis();
- for(int i=0;i<5;i++) {
- new Thread() {
- @Override
- public void run() {
- System.out.println(currentThread().getName()+"开始执行..");
- try {
- sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(currentThread().getName()+"结束执行..");
- }
- }.start();
- }
- long endTime = System.currentTimeMillis();
- System.out.println("多线程运行时间:"+(endTime-startTime)+"ms");//2ms
- System.out.println("主线程结束");
- }
运行结果如下
很显然,这是一个失败的答案。因为我们知道多线程(包括main线程)是抢占CPU执行资源的,所以一旦几个线程处于就绪状态的话,都有机会抢到执行的机会。所以,我们的两处求系统时间的地方都是我们不希望的时间。
也就是说,我们希望结果应该是这样的,“主线程开始”-->5个子线程执行-->“主线程结束”。
3、成功的例子
- public static void main(String args[]) throws InterruptedException {
- CountDownLatch latch = new CountDownLatch(5);//设置计数值
- System.out.println("主线程开始");
- long startTime = System.currentTimeMillis();
- for(int i=0;i<5;i++) {
- new Thread() {
- @Override
- public void run() {
- System.out.println(currentThread().getName()+"开始执行..");
- try {
- sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(currentThread().getName()+"结束执行..");
- latch.countDown();
- }
- }.start();
- }
- latch.await();
- long endTime = System.currentTimeMillis();
- System.out.println("多线程运行时间:"+(endTime-startTime)+"ms");//1007ms
- System.out.println("主线程结束");
- }
运行结果如下
这次是结果是我们想要的。
同时,我们也看到了,5个线程,每个线程需要执行 1s (停止 1s),最终 5 个线程全部执行,只需要1s多点,而不是 5s,这就是多线程的作用。
Java中CountDownLatch的使用和求多线程的运行时间相关推荐
- java中什么是线程安全_Java 多线程:什么是线程安全性
线程安全性 什么是线程安全性 <Java Concurrency In Practice>一书的作者 Brian Goetz 是这样描述"线程安全"的:"当多 ...
- JAVA中0 结果_Java练习题-求1000!的结果中包含多少个0
import java.math.BigDecimal; /** * 求1000!的结果中包含多少个0?注:1000! = 1×2×3×4×5×-×999×1000 * @author Tang * ...
- java中线程调度遵循的原则_Java 多线程(三) 线程的生命周期及优先级
线程的生命周期 线程的生命周期:一个线程从创建到消亡的过程. 如下图,表示线程生命周期中的各个状态: 线程的生命周期可以分为四个状态: 1.创建状态: 当用new操作符创建一个新的线程对象时,该线程处 ...
- Java中CountDownLatch类
创建CountDownLatch对象时,会传入一个count数值,该对象每次调用countDown()方法会使count -- ,就是count每次减1; 调用await()方法,程序会阻塞等待,当 ...
- java while循环 计算机,java中如何利用while循环求n的阶乘
实现思路: 1.定义两个变量,分别用来保存表示阶乘的数和阶乘结果: 2.利用while循环计算阶乘: 3.打印阶乘的结果即可. (视频教程推荐:java视频教程) 具体代码如下:package hel ...
- Java面试中,一些常见的有关多线程问题!
面试作为入职的第一道门槛,其重要性不言而喻.对于从事IT的很多工作人员而言,对面试往往信心不足,毕竟在真实面试中,会遇到很多技术问题,万一哪块技术点不熟,就会与心仪的offer失之交臂.接下来,小千以 ...
- java中的变量是原子的_Java原子变量
概述 多个线程操作共享变量(Java堆内存上的数据)会带来bug,Java提供了锁机制(Lock)来管理多线程并发,比如synchronized,但是会带来额外的性能开销(线程阻塞,上下文切换等).为 ...
- [Java高并发系列(5)][详细]Java中线程池(1)--基本概念介绍
1 Java中线程池概述 1.1 什么是线程池? 在一个应用当中, 我们往往需要多次使用线程, 这意味着我们需要多次创建和销毁线程.那么为什么不提供一个机制或概念来管理这些线程呢? 该创建的时候创建, ...
- java多线程中CountDownLatch和join的使用
在工作中,我们经常需要和多线程打交道,简单说明一个场景,在工厂流水线上有2条流水线,流水线同时开工生产零件,但是每个零件生产时间不一样,只有等到两个零件都生产完毕之后才能开始总组装.那我们很快想到jo ...
- java惰性计算原理_利用 Lambda 表达式实现 Java 中的惰性求值
Java 中惰性求值的潜能,完全被忽视了(在语言层面上,它仅被用来实现 短路求值 ).更先进的语言,如 Scala,区分了传值调用与传名调用,或者引入了 lazy 这样的关键字. 尽管 Java 8 ...
最新文章
- js解决iframe跨域问题
- 博图只能通过地址相同设备找到plc_小白求教:博途v13无法连接s7-1200,显示在网络上未找到任何设备...
- 获得本机的IP,掩码和网关
- 阿里云ECS使用cloudfs4oss挂载OSS
- 功能测试——医疗管理系统
- 【paper】BlazeFace: Sub-millisecond Neural Face Detection on Mobile GPUs
- yii 引用php文件,Yii中引出php文件及插件
- 迁移桌面程序到MS Store(8)——通过APPX下载Win32Component
- 专访声智科技陈孝良:把自己嫁给公司,伟大都是熬出来的
- SLAM之g2o安装
- java中GC的基本概念
- JavaWeb中的四大作用域
- canvas图形操作(缩放、旋转、位移)
- MGR 8.0 + ProxySQL 2.0 部署实录
- RHEL 7.0已发布CentOS 7即将到来
- SLAM中的退化问题
- HPE升级Integrity服务器采用最新安腾引擎
- 爱卓越java_以培养卓越工程师为目标的渐进式项目案例教学法研究——以java实验教学为例...
- uni-app项目总结
- 未来又一新热点,共享房屋初创公司正在起飞
热门文章
- configurationproperties_Spring Boot中@ConfigurationProperties注解实现原理源码解析
- bzoj2697特技飞行*
- 制作windows7系统的U盘启动盘
- 解决在IE浏览器中JQuery.resize()执行多次的方法(转)
- 2000,XP中显示器和系统匹配的问题?
- Unity的包体压缩以及音效优化
- ARM基础相关寄存器的讲解-LPC21XX
- 计算机WORD列宽行高怎么设置,高会《职称计算机》Word 2007:设置行高和列宽
- php隐藏json数据,PHP调用出json后出来的数目字 想隐藏掉 50份求高手帮忙下
- java button 背景色_以编程方式删除UIButton背景颜色