Java并发包之CountDownLatch用法
CountDownLatch计数器闭锁是一个能阻塞主线程,让其他线程满足特定条件下主线程再继续执行的线程同步工具。
Latch闭锁的意思,是一种同步的工具类。类似于一扇门:在闭锁到达结束状态之前,这扇门一直是关闭着的,不允许任何线程通过,当到达结束状态时,这扇门会打开并允许所有的线程通过。且当门打开了,就永远保持打开状态。
CountDowmLatch是一种灵活的闭锁实现,包含一个计数器,该计算器初始化为一个正数,表示需要等待事件的数量。countDown方法递减计数器,表示有一个事件发生,而await方法等待计数器到达0,表示所有需要等待的事情都已经完成。
这句话的意思是:在单独主线程的情况下,创建多个子线程, 在保证主线程同步的情况下,同时又让多个子线程处理,可以使用 CountDownLatch来阻塞主线程,等待子线程执行完成,主线程才执行后续操作.
常见案例:
1:多线程读取批量文件, 并且读取完成之后汇总处理
2:多线程读取Excel多个sheet,读取完成之后获取汇总获取的结果
3:多个人一起一起来吃饭,主人等待客人到来,客人一个个从不同地方来到饭店,主人需要等到所有人都到来之后,才能开饭
4:汽车站,所有乘客都从不同的地方赶到汽车站,必须等到所有乘客都到了,汽车才会出发,如果设置了超时等待,那么当某个时间点到了,汽车也出发
作用:可以用来确保某些活动直到其他活动都完成后才继续执行。
注意事项:
使用CountDownLatch必须确保计数器数量与子线程数量一致,且countDown必须要执行,否则出现计数器不为0,导致主线程一致等待的情况
在执行任务的线程中,使用了try...finally结构,该结构可以保证创建的线程发生异常时CountDownLatch.countDown()方法也会执行,也就保证了主线程不会一直处于等待状态。
CountDownLatch非常适合于对任务进行拆分,使其并行执行,比如某个任务执行2s,其对数据的请求可以分为五个部分,那么就可以将这个任务拆分为5个子任务,分别交由五个线程执行,执行完成之后再由主线程进行汇总,此时,总的执行时间将决定于执行最慢的任务,平均来看,还是大大减少了总的执行时间。
具体代码示例:
模拟乘客登机的场景
package com.puppy.demo; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; //刘小品
public class CountDownLatchTest { public static void main(String[] args) throws InterruptedException { System.out.println("南京禄口机场_机长正在等待所有乘客登机");
//CountDownLatch的计数器数量必须与线程的数量一致,否则可能出现一直等待的情况,即计数器不为0的情况
//使用CountDownLatch 需要注意,子线程中的countDown()最好放到finnally里面,防止计数器不为0
CountDownLatch latch = new CountDownLatch(3); ExecutorService ex = Executors.newCachedThreadPool();
ex.execute(new ThreadTest1(latch));
ex.execute(new ThreadTest2(latch));
ex.execute(new ThreadTest3(latch));
//等待所有乘客来机场
System.out.println("所有乘客都在赶飞机的路上"); //latch.await(1,TimeUnit.SECONDS);//模拟超时等待的情况
latch.await(); //模拟等待的情况,不考虑子线程的处理实际
System.out.println("南京禄口机场_机长启动飞机起飞");
ex.shutdown();
} } class ThreadTest1 extends Thread { CountDownLatch lanch; public ThreadTest1() { } public ThreadTest1(CountDownLatch lanch) {
this.lanch = lanch;
} @Override
public void run() {
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场");
lanch.countDown();
}
} class ThreadTest2 extends Thread { CountDownLatch lanch; public ThreadTest2() { } public ThreadTest2(CountDownLatch lanch) {
this.lanch = lanch;
} @Override
public void run() {
System.out.println("正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场");
lanch.countDown();
}
} class ThreadTest3 extends Thread {
CountDownLatch lanch; public ThreadTest3() { } public ThreadTest3(CountDownLatch lanch) {
this.lanch = lanch;
} @Override
public void run() {
System.out.println("正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场");
lanch.countDown();
}
}
执行结果
latch.await()
南京禄口机场_机长正在等待所有乘客登机
所有乘客都在赶飞机的路上
正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场
正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场
正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场
南京禄口机场_机长启动飞机起飞
超时等待的情况:latch.await(1,TimeUnit.SECONDS)
主线程已经执行完成,但是子线程才结束,latch.await(1,TimeUnit.SECONDS)方法
南京禄口机场_机长正在等待所有乘客登机
所有乘客都在赶飞机的路上
正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场
正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场
南京禄口机场_机长启动飞机起飞
正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场
Java并发包之CountDownLatch用法的更多相关文章
- Java并发包中CountDownLatch的工作原理、使用示例
1. CountDownLatch的介绍 CountDownLatch是一个同步工具,它主要用线程执行之间的协作.CountDownLatch 的作用和 Thread.join() 方法类似,让一些线 ...
- Java并发包之Semaphore用法
多线程中的同步概念就是排着队去执行一个任务,执行任务的是一个一个的执行,并不能并行执行,这样的优点是有助于程序逻辑的正确性,不会出现线程安全问题,保证软件的系统功能上的运行稳定性, Semaphore ...
- Java并发包源码学习系列:同步组件CountDownLatch源码解析
目录 CountDownLatch概述 使用案例与基本思路 类图与基本结构 void await() boolean await(long timeout, TimeUnit unit) void c ...
- Java并发包基石-AQS详解
目录 1 基本实现原理 1.1 如何使用 1.2 设计思想 2 自定义同步器 2.1 同步器代码实现 2.2 同步器代码测试 3 源码分析 3.1 Node结点 3.2 独占式 3.3 共享式 4 总 ...
- java并发包&线程池原理分析&锁的深度化
java并发包&线程池原理分析&锁的深度化 并发包 同步容器类 Vector与ArrayList区别 1.ArrayList是最常用的List实现类,内部是通过数组实现的, ...
- Java并发包下的几个API
并发包 (计数器)CountDownLatch (屏障)CyclicBarrier (计数信号量)Semaphore 案例: 需求: 代码: 并发包 (计数器)CountDownLatch Coun ...
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...
- Java并发包源码学习之AQS框架(三)LockSupport和interrupt
接着上一篇文章今天我们来介绍下LockSupport和Java中线程的中断(interrupt). 其实除了LockSupport,Java之初就有Object对象的wait和notify方法可以实现 ...
- Java并发包源码学习之AQS框架(一)概述
AQS其实就是java.util.concurrent.locks.AbstractQueuedSynchronizer这个类. 阅读Java的并发包源码你会发现这个类是整个java.util.con ...
随机推荐
- BootStrap有用代码片段(持续总结)
> 如题.持续总结自己在使用BootStrap中遇到的问题.并记录解决方法.希望能帮到须要的小伙伴 1.bootstrap上下布局.顶部固定下部填充 应用场景:经典上下布局中,顶部导航条固定,下 ...
- Android微信智能心跳方案 Android微信智能心跳方案
原文地址: http://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=207243549&idx=1&sn=4ebe4beb81 ...
- windows 快捷调用
win + x:系统常用管理工具: win + r,或者按下 windows 键,在输入框中输入: services.msc:服务管理: diskmgmt.msc:磁盘管理: devmgmt.msc: ...
- 解读邮箱正则表达式:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
转自:http://www.cnblogs.com/joyceTING/archive/2013/05/09/3069089.html正则表达式 \w+([-+.]\w+)*@\w+([-.]\w+) ...
- spring的quartz定时任务
一.版本: 1.spring:4.1.7: 2.quartz:2.2.1: 二.基于ssm项目: 1.引入jar包:quartz-2.2.1.jar:spring所需包. 2.说明:quartz ...
- jquery实现上下浮动
jquery实现上下浮动: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- Android实现App版本自动更新
现在很多的App中都会有一个检查版本的功能.例如斗鱼TV App的设置界面下: 当我们点击检查更新的时候,就会向服务器发起版本检测的请求.一般的处理方式是:服务器返回的App版本与当前手机安装的版本号 ...
- Gson解析List的一点小问题
这阵子在使用gson解析时遇到了点小麻烦,因为一直用的fastjson,最近一个项目里使用的gson,需要解析list集合,查资料都是使用TypeToken解决,相对比较麻烦,下面为大伙推荐一种简便的 ...
- HTML图片映射
<img>图片映射 <map>与<area>一起使用来定义一个图像映射(一个可点击的链接区域). <img src="cat.jpg" a ...
- ubuntu 同时安装anaconda2和anaconda3
说明:先根据Ubuntu预装的python2.7来安装Anaconda2,然后将Anaconda3作为其环境安装在envs文件夹下. 重要提示:有一些软件需要py2.7的环境,比如XX-Net, 最好 ...