两种方案实现等待线程池结束后执行后面的业务代码

使用场景

  1. 批量任务处理:当需要并发执行多个任务,然后等待所有任务执行完毕后进行下一步操作时,可以使用这两种方法来等待所有任务执行完毕。

  2. 线程池管理:在使用线程池执行任务时,有时需要等待所有任务执行完毕后再关闭线程池,可以使用这两种方法来实现这一需求。

  3. 并发测试:在并发测试中,有时需要等待所有测试线程执行完毕后再进行结果汇总和分析,这时可以使用这两种方法来等待所有测试线程执行完毕。

总之,无论是在需要等待多个任务执行完毕后再进行下一步操作的业务场景,还是在线程池管理或并发测试等技术领域,这两种方法都可以非常有用。它们能够帮助实现多线程任务的协同和管理,确保所有任务都执行完毕后再进行后续操作。

使用CountDownLatch的方案

代码
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.CountDownLatch;public class ThreadPoolExample {public static void main(String[] args) throws InterruptedException {int threadCount = 5;ExecutorService executor = Executors.newFixedThreadPool(threadCount);CountDownLatch latch = new CountDownLatch(threadCount);List<Integer> list=new ArrayList<>();for (int i = 0; i < threadCount; i++) {int finalI = i;executor.submit(() -> {// 执行线程任务try {System.out.println(finalI);int i1 = get();System.out.println("===============================");list.add(i1);} catch (InterruptedException e) {throw new RuntimeException(e);}// 任务执行完毕后,调用countDown()latch.countDown();});}// 等待所有线程执行完毕latch.await();// 关闭线程池executor.shutdown();System.out.println("******************************");System.out.println(list);}public static int get() throws InterruptedException {Thread.sleep(3000);return new Random().nextInt(30);}
}
结果

在这里插入图片描述

原理和注释:
  • 创建一个固定大小的线程池,并使用CountDownLatch来等待所有线程执行完毕。
  • 每个线程执行完毕后都会调用countDown()方法来减少计数器的值,当计数器的值为0时,await()方法就会返回,表示所有线程执行完毕。
  • 最后,调用shutdown()方法来关闭线程池。

使用awaitTermination的方案

代码
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.Random;public class ThreadPoolExample {public static void main(String[] args) throws InterruptedException {int threadCount = 5;ExecutorService executor = Executors.newFixedThreadPool(threadCount);List<Integer> list=new ArrayList<>();for (int i = 0; i < threadCount; i++) {int finalI = i;executor.submit(() -> {// 执行线程任务try {System.out.println(finalI);int i1 = get();System.out.println("===============================");list.add(i1);} catch (InterruptedException e) {throw new RuntimeException(e);}});}// 关闭线程池executor.shutdown();executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); // 等待所有任务执行完毕System.out.println("************************************");System.out.println(list);// 所有任务执行完毕后会继续执行这里的代码}public static int get() throws InterruptedException {Thread.sleep(3000);return new Random().nextInt(30);}
}
运行截图

在这里插入图片描述

原理和注释:
  • 创建一个固定大小的线程池,并使用executor.shutdown()来关闭线程池。
  • 使用executor.awaitTermination()来等待所有任务执行完毕。当所有任务执行完毕后,awaitTermination会返回,然后可以继续执行后续的代码。

需要注意的点

在使用这两种方法等待线程执行完毕时,需要注意以下几点:

  1. 确保所有线程都能够正常执行完毕,否则可能会出现死锁等问题。

  2. 在使用CountDownLatch等待线程执行完毕时,需要在每个线程的任务执行完毕后调用countDown()方法,否则计数器的值不会减少,就会一直等待下去。

  3. 在使用awaitTermination等待线程执行完毕时,需要调用shutdown()方法来关闭线程池,否则线程池会一直等待新的任务到来,无法退出。

  4. 在使用awaitTermination等待线程执行完毕时,需要注意超时时间的设置,否则可能会一直等待下去。

  5. 在使用多线程时,需要注意线程安全问题,避免出现竞态条件等问题。

总之,在使用这两种方法等待线程执行完毕时,需要仔细考虑业务逻辑和线程安全问题,确保程序能够正确地执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/286754.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

零基础也能制作家装预约咨询小程序

近年来&#xff0c;随着互联网的快速发展&#xff0c;越来越多的消费者倾向于使用手机进行购物和咨询。然而&#xff0c;许多家装实体店却发现自己的客流量越来越少&#xff0c;急需一种新的方式来吸引顾客。而开发家装预约咨询小程序则成为了一种利用互联网技术来解决这一问题…

标准IO与文件IO

标准IO通过缓冲机制减少系统调用&#xff0c;实现更高的效率 全缓冲&#xff1a;当流的缓冲区无数据或无空间时才执行实际IO操作 行缓冲&#xff1a;当在输入和输出中遇到换行符&#xff08;\n&#xff09;时&#xff0c;进行IO操作 当流和一个终端关联时&#xff0c;典型的行缓…

python学习,2.简单的数据类型

1.了解数及运算 整数&#xff1a;1&#xff0c;2&#xff0c;3。 运算符&#xff1a;加减乘除&#xff0c;**(乘方) 浮点数&#xff1a;python将所有带小数点的数称为浮点数。 这一块和别的语言有些不一样&#xff0c; 像C&#xff0c;分为float&#xff0c;double&#x…

基于grpc从零开始搭建一个准生产分布式应用(7) - 01 - 附:GRPC拦截器源码

开始前必读&#xff1a;​​基于grpc从零开始搭建一个准生产分布式应用(0) - quickStart​​ 一、源码目录结构 二、GRPC拦截器源码 2.1、com.zd.baseframework.core.core.common.interceptor package com.zd.baseframework.core.core.common.interceptor;import com.zd.ba…

清华提出ViLa,揭秘 GPT-4V 在机器人视觉规划中的潜力

人类在面对简洁的语言指令时&#xff0c;可以根据上下文进行一连串的操作。对于“拿一罐可乐”的指令&#xff0c;若可乐近在眼前&#xff0c;下意识的反应会是迅速去拿&#xff1b;而当没看到可乐时&#xff0c;人们会主动去冰箱或储物柜中寻找。这种自适应的能力源于对场景的…

算法(2)——滑动窗口

前言&#xff1a; 步骤及算法模板&#xff1a; 确定两个指针变量&#xff0c;left0,right0; 进窗口&#xff1a; 判断&#xff1a; 出窗口 更新结果 接下来我们的所用滑动窗口解决问题都需要以上几个步骤。 一、长度最小的子数组 209. 长度最小的子数组 - 力扣&#xff08;L…

【重点】【前缀树|字典树】208.实现Trie(前缀树)

题目 前缀树介绍&#xff1a;https://blog.csdn.net/DeveloperFire/article/details/128861092 什么是前缀树 在计算机科学中&#xff0c;trie&#xff0c;又称前缀树或字典树&#xff0c;是一种有序树&#xff0c;用于保存关联数组&#xff0c;其中的键通常是字符串。与二叉查…

安卓开发学习---kotlin版---笔记(三)

网络 安卓主页的网络框架&#xff1a;OkHttp 在OkHttp的基础上进行封装的&#xff1a;Retrofit框架&#xff0c;更常使用 OkHttp学习 在使用网络请求的时候&#xff0c;先添加网络访问权限&#xff1a; <uses-permission android:name"android.permission.INTERNET&…

JavaScript 内存管理的秘密武器:垃圾回收(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

SQL进阶理论篇(十四):CBO优化器是如何计算代价的?

文章目录 简介能调整的代价模型的参数有哪些&#xff1f;mysql.server_costmysql.engine_cost 如何修改这些代价参数&#xff1f;代价模型具体是如何计算的参考文献 简介 大部分RDBMS都支持基于代价的优化器CBO&#xff0c;但其实CBO仍然存在缺陷&#xff08;比如参数配置的不…

Android 原始方法实现Tablayout样式

源码&#xff1a; 【免费】Android原始方法实现Tablayout样式资源-CSDN文库 推荐&#xff1a; GitHub - hackware1993/MagicIndicator: A powerful, customizable and extensible ViewPager indicator framework. As the best alternative of ViewPagerIndicator, TabLayout …

3dsmax渲染太慢,用云渲染农场多少钱?

对于许多从事计算机图形设计的创作者来说&#xff0c;渲染速度慢是一个常见问题&#xff0c;尤其是对于那些追求极致出图效果的室内设计师和建筑可视化师&#xff0c;他们通常使用3ds Max这样的工具&#xff0c;而高质量的渲染经常意味着长时间的等待。场景复杂、细节丰富&…