首页 > 基础资料 博客日记
Java中使用CountDownLatch实现并发流程控制
2023-08-11 20:47:29基础资料围观225次
场景
CountDownLatch,它是 JDK 提供的并发流程控制的工具类,它是在 java.util.concurrent 包下,在 JDK1.5 之后加入的。
应用场景举例:
5个运动员参加马拉松比赛,好比五个线程,每个人跑完的时间不同,而比赛成绩统计必须要等待5个运动员都跑完才能往下进行。
实现流程可以参考下图
最开始 CountDownLatch 设置的初始值为 3,而后 T0 线程上来就调用 await 方法,它的做用是让这个线程开始等待,等待后面的 T一、T二、T3,它们每一次调用 countDown 方法,3 这个数值就会减 1,也就是从 3 减到 2,从 2 减到 1,从 1 减到 0,一旦减到 0 以后,这个 T0 就达到了本身触发继续运行的条件,因而它就恢复运行了。
主要方法
构造函数:
public CountDownLatch(int count) { };它的构造函数是传入一个参数,该参数 count 是须要倒数的数值。
await():
调用 await() 方法的线程开始等待,直到倒数结束,也就是 count 值为 0 的时候才会继续执行。
await(long timeout, TimeUnit unit):
await() 有一个重载的方法,里面会传入超时参数,这个方法的做用和 await() 相似,可是这里能够设置超时时间,
若是超时就再也不等待了。
countDown():
把数值倒数 1,也就是将 count 值减 1,直到减为 0 时,以前等待的线程会被唤起。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
1、使用ExecutorService搭建线程池
Java中ExecutorService线程池的使用(Runnable和Callable多线程实现):
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/126242904
参考如上。
2、然后新建countDownLatch,并设定计数器为5
CountDownLatch countDownLatch = new CountDownLatch(5);
这里的5与具体业务相关,比如这里模拟5个任务执行。
3、在主进程中设置await
public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(5); ExecutorService executorService = Executors.newFixedThreadPool(5); for (int i = 0; i < 5; i++) { executorService.submit(new TestTask(countDownLatch)); } System.out.println("等待所有线程全部结束......"); countDownLatch.await(); System.out.println("线程全部结束"); }
4、在任务执行类中通过构造方法传递countDownLatch,并在每个任务中通过随机数模拟不同任务的执行时间。
在每个任务执行结束之后调用latch.countDown(),使计数器减1。
class TestTask implements Runnable { private CountDownLatch latch; public CountDownLatch getLatch() { return latch; } public void setLatch(CountDownLatch latch) { this.latch = latch; } public TestTask(CountDownLatch latch) { this.latch = latch; } @Override public void run() { String threadName = Thread.currentThread().getName(); try { Thread.sleep((long) (Math.random() * 10000)); System.out.println("线程名:" + threadName + " 结束时间:" + DateUtils.getTime()); } catch (InterruptedException e) { e.printStackTrace(); }finally { latch.countDown(); } } }
5、完整示例代码
package com.ruoyi.demo.Executor; import com.ruoyi.common.utils.DateUtils; import java.util.concurrent.*; public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(5); ExecutorService executorService = Executors.newFixedThreadPool(5); for (int i = 0; i < 5; i++) { executorService.submit(new TestTask(countDownLatch)); } System.out.println("等待所有线程全部结束......"); countDownLatch.await(); System.out.println("线程全部结束"); } } class TestTask implements Runnable { private CountDownLatch latch; public CountDownLatch getLatch() { return latch; } public void setLatch(CountDownLatch latch) { this.latch = latch; } public TestTask(CountDownLatch latch) { this.latch = latch; } @Override public void run() { String threadName = Thread.currentThread().getName(); try { Thread.sleep((long) (Math.random() * 10000)); System.out.println("线程名:" + threadName + " 结束时间:" + DateUtils.getTime()); } catch (InterruptedException e) { e.printStackTrace(); }finally { latch.countDown(); } } }
6、执行效果
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: