java 并发执行批量异步任务(Future、 CompletableFuture 实现)

文章目录

  • 前言
  • 一、创建线程池
  • 二、Future 类并发实现
  • 三、CompletableFuture 类并发实现


前言

当我们需要批量执行一些比较耗时任务时,使用并发的方式减少业务处理的整体时间,防止客户端响应时间过长。


一、创建线程池

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.ThreadPoolExecutor;/*** @ClassName : ThreadPoolConfig* @Description : ThreadPoolConfig* @Author : zhuguangkui* @Date: 2022-08-03*/
@Configuration
@Slf4j
public class ThreadPoolConfig {@AutowiredThreadPoolProperties threadPoolProperties;/*** 获得Java虚拟机可用的处理器个数 + 1*/private static final int THREADS = Runtime.getRuntime().availableProcessors() + 1;/***   默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,*  当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;*  当队列满了,就继续创建线程,当线程数量大于等于maxPoolSize后,开始使用拒绝策略拒绝*/@Bean(name = "varHandleThreadPool")public ThreadPoolTaskExecutor varHandleThreadPool(){int corePoolSizeConfig = threadPoolProperties.getCorePoolSizeConfig();//核心线程数int corePoolSize = corePoolSizeConfig ==0 ? THREADS : corePoolSizeConfig;ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setMaxPoolSize(2 * corePoolSize);executor.setCorePoolSize(corePoolSize);executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());executor.setThreadNamePrefix(threadPoolProperties.getThreadNamePrefix());// 线程池对拒绝任务(无线程可用)的处理策略// CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());// 初始化executor.initialize();log.info("doc 线程池初始化配置:{},THREADS:{}", threadPoolProperties, THREADS);return executor;}
}

二、Future 类并发实现

/*** 批量并发处理业务*/
@Override
public void generateBatchFile(List<String> fileNameList) {List<Future<IdocDoc>> futureList = new ArrayList<>(); // 并发处理结果集// 批量处理业务for (String fileName : fileNameList) {Future<IdocDoc> future = generateFile(fileName);futureList.add(future);}// 依次获取异步结果while (true) {for (Future<IdocDoc> future : futureList) {if (future.isDone() && !future.isCancelled()) { // 判断任务执行是否完成IdocDoc idocDoc = future.get(); // 获取异步结果idocDocList.add(idocDoc);futureList.remove(future);}}if (CollectionUtil.isEmpty()) {break;}Thread.sleep(1); // 每次轮询休息1毫秒,避免CPU占用}
}/*** 子业务*/
@Async("varHandleThreadPool")
public Future<IdocDoc> generateFile(String fileName) {IdocDoc idoDoc = new IdoDoc();idocDoc.setName(fileName);... // 业务操作// 返回异步结果return new AsyncResult<>(idocDoc);
}

三、CompletableFuture 类并发实现

/*** 批量并发处理业务*/
@Override
public void generateBatchFile(List<String> fileNameList) {List<CompletableFuture<IdocDoc>> futureList = new ArrayList<>(); // 并发处理结果集// 批量处理业务for (String fileName : fileNameList) {CompletableFuture<IdocDoc> future = CompletableFuture.supplyAsync(() -> {return generateFile(fileName);}, threadPoolTaskExecutor);futureList.add(future);}// 依次获取异步结果while (true) {for (CompletableFuture<IdocDoc> future : futureList) {if (future.isDone() && !future.isCancelled()) { // 判断任务执行是否完成IdocDoc idocDoc = future.get(); // 获取异步结果idocDocList.add(idocDoc);futureList.remove(future);}}if (CollectionUtil.isEmpty()) {break;}Thread.sleep(1); // 每次轮询休息1毫秒,避免CPU占用}
}/*** 子业务*/
public IdocDoc generateFile(String fileName) {IdocDoc idoDoc = new IdoDoc();idocDoc.setName(fileName);... // 业务操作// 返回异步结果return idocDoc;
}

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

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

相关文章

授权专利破百,通付盾潜心精研迎接数字时代新征程

2023年10月10日&#xff0c;通付盾发明专利《一种零信任和保护数据隐私的数据确权系统及其方法》获得授权&#xff0c;至此公司授权发明专利突破100件&#xff0c;是公司科创属性的集中展现&#xff0c;也是公司成为数字化高端软件与服务提供商道路上的新里程碑。 自成立以来&a…

掌握C++魔法:深入解析类与对象(上篇)

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; &#x1f354;前言&#xff1a; 之前我们学习了从C语言转到C后我们需要知道的一些关键改动与变化。今天我们就要学习C独有的类与对象。在谈论类与对象之前我们先说一下什么是面向对象的C&#xff0c;什么是面向过程的C语…

【C++之类型转换】static_cast、dynamic_cast、const_cast、reinterpret_cast用途与限制

概述 类型转换是将一个变量的数据类型转换为另一个数据类型的过程。 在C中&#xff0c;有四种类型转换运算符&#xff1a;static_cast、dynamic_cast、const_cast和reinterpret_cast。 1. static_cast: 用途&#xff1a;主要用于基本数据类型和非多态类之间的转换&#xff0…

NSDT孪生编辑器助力智慧城市

技术有能力改变城市的运作方式&#xff0c;提高效率&#xff0c;为游客和居民提供更好的体验&#xff0c;实现更可持续的运营和更好的决策。 当今城市面临的主要挑战是什么&#xff0c;成为智慧城市如何帮助克服这些挑战&#xff1f; 我们生活在一个日益城市化的世界&#xf…

【SA8295P 源码分析 (二)】16 - QNX侧 TouchScreen Panel (TP)线程函数 tp_recv_thread 源码分析

【SA8295P 源码分析】16 - QNX侧 TouchScreen Panel (TP)线程函数 tp_recv_thread 源码分析 一、TP 线程函数:tp_recv_thread()二、处理&上报 坐标数据 cypress_read_touch_data()系列文章汇总见:《【SA8295P 源码分析 (二)】Display 模块 文章链接汇总 - 持续更新中》…

杭电oj--求数列的和

Problem Description 数列的定义如下&#xff1a; 数列的第一项为n&#xff0c;以后各项为前一项的平方根&#xff0c;求数列的前m项的和。 Input 输入数据有多组&#xff0c;每组占一行&#xff0c;由两个整数n&#xff08;n<10000&#xff09;和m(m<1000)组成&#x…

【SA8295P 源码分析 (一)】76 - Thermal 功耗 之 /dev/thermalmgr 相关调试命令汇总

【SA8295P 源码分析】76 - Thermal 功耗 之 /dev/thermalmgr 相关调试命令汇总 1、配置文件:/mnt/etc/system/config/thermal-engine.conf2、获取当前SOC所有温度传感器的温度:cat /dev/thermalmgr3、查看所有 Thermal 默认配置和自定义配置:echo query config > /dev/th…

React之refs

一、是什么 Refs 在计算机中称为弹性文件系统&#xff08;英语&#xff1a;Resilient File System&#xff0c;简称ReFS&#xff09; React 中的 Refs提供了一种方式&#xff0c;允许我们访问 DOM节点或在 render方法中创建的 React元素 本质为ReactDOM.render()返回的组件实…

【复盘】记录一次数据库连接资源占用完毕

背景 因为历史原因项目使用的是JDBC原始SQL&#xff0c;然后进行拉去三方数据进行解析分析。跑了一会之后发现影响到了线上业务&#xff0c;连接错误。 一查看其实就是刚才跑的定时导致的&#xff0c;分析了下没有及时释放数据库连接。导致资源耗尽。数据库异常。 所以这里其实…

Java身份证OCR识别 - 阿里云API【识别准确率超过99%】

1. 阿里云API市场 https://market.aliyun.com/products/57124001/cmapi00063618.html?spm5176.28261954.J_7341193060.41.60e52f3drduOTh&scm20140722.S_market%40%40API%E5%B8%82%E5%9C%BA%40%40cmapi00063618._.ID_market%40%40API%E5%B8%82%E5%9C%BA%40%40cmapi0006361…

美国科技消费品公司Society Brands完成2500万美元融资

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于美国俄亥俄州坎顿的科技消费品公司Society Brands今日宣布已完成2500万美元融资。 本轮融资由Gullane Capital领投&#xff0c;Callais Capital和North Coast Ventures跟投。 该公司打算利…

【一文清晰】单元测试到底是什么?应该怎么做?

我是java程序员出身&#xff0c;后来因为工作原因转到到了测试开发岗位。测试开发工作很多年后&#xff0c;现在是一名自由职业者 1、什么是单元测试 2、该怎么做单元测试 一、什么是单元测试&#xff1f; 单元测试&#xff08;unit testing&#xff09;&#xff0c;是指对软件…

手机拍照转机器人末端坐标(九点标定法)

1.打印标定纸&#xff0c;随机九个点 2.让UR机器人末端分别走到P1-P9九个点 在图示位置读取九个点的X&#xff0c;Y坐标 3.手机拍照&#xff08;固定点&#xff09; 测试可以随机拍一张&#xff0c;实用的话需要固定手机的拍照位置&#xff0c;得到的图片如下&#xff1a; 4.…

【JUC】读写锁

读写锁 文章目录 读写锁1. ReentrantReadWriteLock概述2. 编码演示2.1 ReentrantLock实现2.2 ReentrantReadWriteLock实现 3. ReentrantReadWriteLock3.1 锁降级3.2 锁降级的必要性3.3 饥饿问题 4. StampedLock&#xff08;邮戳锁也叫票据锁&#xff09;4.1 特点4.2 三种访问模…

2023年全网最新 Windows10 搭建 Python 环境教程

目录 一、查看计算机操作系统的位数二、安装Python2.1 下载Python安装包2.2 在Windows 64位系统中安装Python2.3 测试Python是否安装成功 三、Windows环境下安装第2个Python(不同版本) ----不需要安装多个Python版本的读者此小节可以忽略 一、查看计算机操作系统的位数 目前&a…

【脉冲通信】用于空间应用的飞秒脉冲通信的符号误码率模型研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Android 第三方app https 抓包

工具选择 Charles 或 Fiddler 都可以 在PC上安装工具并进行设置 Charles Fiddler 设置按官网说明设置一下好。 Charles设置 Fiddler设置 Android Api Level > 24 SSL特殊设置 当Android 的 Api Level > 24时需要修改一下app的一起配置 1.在项目中添加 Android/src/…

【C++笔记】多态的原理、单继承和多继承关系的虚函数表、 override 和 final、抽象类、重载、覆盖(重写)、隐藏(重定义)的对比

1.final关键字 引出&#xff1a;设计一个不能被继承的类。有如下方法&#xff1a; class A { private:A(int a0):_a(a){} public:static A CreateOBj(int a0){return A(a);} protected:int _a; } //简介限制&#xff0c;子类构成函数无法调用父类构造函数初始化 //子类的构造…

IDEA如何拉取gitee项目?

1.登录gitee 说明&#xff1a;打开idea&#xff0c;在设置上面搜索框输入gitee&#xff0c;然后登录gitee注册的账号。 2. 创建gitee仓库 说明&#xff1a;创建idea中的gitee仓库。 3.寻找项目文件 说明&#xff1a;为需要添加gitee仓库的项目进行添加。 4.项目右键 说明&a…

el-tree 获取功率后的树结构

正常来说element框架应该返回的&#xff0c;但实际上没有&#xff0c;只能自己处理了 递归处理&#xff0c;思路就是赋值&#xff0c;如果是自己过滤到的数据就push进去&#xff0c;不是就不要 let newCheckTree [] let tree get_tree(treeData,newCheckTree); //获取过滤…