java countdownlatch_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个子任务,分别交由五个线程执行,执行完成之后再由主线程进行汇总,此时,总的执行时间将决定于执行最慢的任务,平均来看,还是大大减少了总的执行时间。

具体代码示例:

模拟乘客登机的场景

packagecom.puppy.demo;importjava.util.concurrent.CountDownLatch;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.TimeUnit;//刘小品

public classCountDownLatchTest {public static void main(String[] args) throwsInterruptedException {

System.out.println("南京禄口机场_机长正在等待所有乘客登机");//CountDownLatch的计数器数量必须与线程的数量一致,否则可能出现一直等待的情况,即计数器不为0的情况//使用CountDownLatch 需要注意,子线程中的countDown()最好放到finnally里面,防止计数器不为0

CountDownLatch latch = new CountDownLatch(3);

ExecutorService ex=Executors.newCachedThreadPool();

ex.execute(newThreadTest1(latch));

ex.execute(newThreadTest2(latch));

ex.execute(newThreadTest3(latch));//等待所有乘客来机场

System.out.println("所有乘客都在赶飞机的路上");//latch.await(1,TimeUnit.SECONDS);//模拟超时等待的情况

latch.await(); //模拟等待的情况,不考虑子线程的处理实际

System.out.println("南京禄口机场_机长启动飞机起飞");

ex.shutdown();

}

}class ThreadTest1 extendsThread {

CountDownLatch lanch;publicThreadTest1() {

}publicThreadTest1(CountDownLatch lanch) {this.lanch =lanch;

}

@Overridepublic voidrun() {try{

Thread.sleep(2000L);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println("正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场");

lanch.countDown();

}

}class ThreadTest2 extendsThread {

CountDownLatch lanch;publicThreadTest2() {

}publicThreadTest2(CountDownLatch lanch) {this.lanch =lanch;

}

@Overridepublic voidrun() {

System.out.println("正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场");

lanch.countDown();

}

}class ThreadTest3 extendsThread {

CountDownLatch lanch;publicThreadTest3() {

}publicThreadTest3(CountDownLatch lanch) {this.lanch =lanch;

}

@Overridepublic voidrun() {

System.out.println("正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场");

lanch.countDown();

}

}

执行结果

latch.await()

南京禄口机场_机长正在等待所有乘客登机

所有乘客都在赶飞机的路上

正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场

正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场

正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场

南京禄口机场_机长启动飞机起飞

超时等待的情况:latch.await(1,TimeUnit.SECONDS)

主线程已经执行完成,但是子线程才结束,latch.await(1,TimeUnit.SECONDS)方法

南京禄口机场_机长正在等待所有乘客登机

所有乘客都在赶飞机的路上

正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场

正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场

南京禄口机场_机长启动飞机起飞

正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值