Springboot @Async 多线程获取返回值
Springboot @Async 多线程获取返回值
需求背景
最近需要用到多线程, 自己维护线程池很麻烦, 正好看到Springboot集成线程池的例子, 这里自己做了个尝试和总结, 记录一下, 也分享给需要的朋友;
不考虑事务的情况下, 这个多线程实现比较简单, 主要有以下几点:
- 在启动类加上
@EnableAsync注解, 开启异步执行支持; - 编写线程池配置类, 别忘了
@Configuration, 和@Bean注解; - 编写需要异步执行的业务, 放到单独的类中 (可以定义为 service, 因为需要 spring 管理起来才能用 );
举栗个现实问题:
需求:拉取 业务数据不能超过 5秒。
拉取第三方数据 ,分别需要拉取 A业务数据(需要2秒) 、拉取 B业务数据(需要2秒)、拉取 C业务数据(需要2秒) ,最后再一并返回给前端。
解决方案: Executor+@Async(“参数”)+CompletableFuture 或 Future
上代码
1.启动类上加注解
@EnableAsync
2.配置类
其他配置请参考配置类示例
@Slf4j
//@EnableAsync//(该注解加在启动类或线程池配置类上都可以)
@Configuration
public class ThreadPoolCommonConfig extends AsyncConfigurerSupport {@Bean("asyncExecutor")public Executor asyncExecutor() {ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();taskExecutor.setCorePoolSize(20);taskExecutor.setMaxPoolSize(100);taskExecutor.setQueueCapacity(1000);taskExecutor.setKeepAliveSeconds(60);taskExecutor.setThreadNamePrefix("asyncExecutorConfig--");taskExecutor.setWaitForTasksToCompleteOnShutdown(true);taskExecutor.setAwaitTerminationSeconds(60);taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());// MDC 装饰器 传递MDC中的信息taskExecutor.setTaskDecorator(new MdcTaskDecorator());return taskExecutor;}
}
3.异步方法(所属类需交由Spring管理)
3.1.@Async + CompletableFuture(推荐)
@Override
@Async("asyncExecutor")
public CompletableFuture<String> list(String s) {log.info("{}: {}", s, Thread.currentThread().getName());ThreadUtil.sleep(2, TimeUnit.SECONDS);log.info("{}查询列表成功", s);return CompletableFuture.completedFuture(s);
}
3.2.@Async + Future
// 异步执行的方法, 注解内为自定义线程池类名
@Override
@Async("asyncExecutor")
public Future<Integer> test(Integer i) {log.info("{}: {}", i, Thread.currentThread().getName());ThreadUtil.sleep(1, TimeUnit.SECONDS);log.info("@Async执行:{}", i);return new AsyncResult(i);
}
4.调用
4.1.CompletableFuture获取返回值(推荐)
CompletableFuture<String> future1 = testService.list("A");
CompletableFuture<String> future2 = testService.list("B");
// 阻塞所有异步线程执行完毕
CompletableFuture.allOf(future1, future2).join();
// 阻塞,直至 future1 和 future2 的异步线程执行完毕
log.info("future结果:{},{}", future1.get(), future2.get());
4.2.Future获取返回值
Future<Integer> future1 = testService.test(1);
Future<Integer> future2 = testService.test(2);
// 阻塞,直至 future1 的异步线程执行完毕
log.info("future1结果:{}", future1.get());
// 阻塞,直至 future2 的异步线程执行完毕
log.info("future1结果:{}", future2.get());
参考文档
Async注解使用和CompletableFuture注解获取返回值
Springboot @Async 多线程获取返回值
Spring Boot中调用@Async注解的异步方法并获取返回值
相关文章:
Springboot @Async 多线程获取返回值
Springboot Async 多线程获取返回值 需求背景 最近需要用到多线程, 自己维护线程池很麻烦, 正好看到Springboot集成线程池的例子, 这里自己做了个尝试和总结, 记录一下, 也分享给需要的朋友; 不考虑事务的情况下, 这个多线程实现比较简单, 主要有以下几点: 在启动类加上Enab…...
怎样接入chatGPT
官网链接: OpenAI platform...
Docker consul容器服务更新与发现
Docker consul容器服务更新与发现 一、什么事服务注册与发现二、什么是consul三、consul部署1、consul服务器2、registrator服务器3、consul-template 一、什么事服务注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的,不保障高可…...
[算法很美打卡] 多维数组篇 (打卡第一天)
文章目录 顺时针打印二维数组0所在的行列清零 顺时针打印二维数组 package 每日算法学习打卡.算法打卡.七月份.七月二十六号;public class test1 {public static void main(String[] args) {int[][] matrix {{1,2},{5,6},{9,10},{13,14},};print(matrix);}static void print(i…...
微服务系列(1)-who i am?
微服务系列(1)-我是谁 应用架构的演化 简单来说系统架构可以分为以下几个阶段:复杂的臃肿的单体架构-SOA架构-微服务 单体架构及其所面临的问题 在互联网发展初期,用户数量少,流量小,硬件成本高。因此…...
记录这这段时间发生的事情。
当做后端的时候总是被骂做前很丑。成为一个UI设计师与后端工程师才会更加完美。 尝试着做一个主页面。 创建了一个主页面 的表格index。 收录了希望发送到主页的,的帖子。 并且,可以填写是否可以。 一个看起来不错的主页。 标题设计的左右框。 这种框…...
发布npm包流程
发布npm包的步骤如下: 在终端中通过 npm init 命令创建一个新的npm包,按照提示填写包的信息,如包名称、版本、描述、作者、许可证等。 在包的根目录下创建一个 index.js 文件,编写你的代码。 确认你已经注册了npm账号࿰…...
面试官:Redis 为什么变慢了?怎么解决?
一、Redis为什么变慢了 二、Redis如何优化 三、Redis变慢了排查步骤 一、Redis为什么变慢了 1.Redis真的变慢了吗? 对 Redis 进行基准性能测试 例如,我的机器配置比较低,当延迟为 2ms 时,我就认为 Redis 变慢了,…...
Docker:开启应用程序开发新篇章的利器
Docker:开启应用程序开发新篇章的利器 引言:1. Docker 的基本概念2. Docker 的优势3. Docker 在应用程序开发中的实际应用如何创建docker镜像如何部署docker镜像结论: 引言: 在现代软件开发领域中,容器化技术正在迅猛…...
Python面向对象(三)(继承、封装)
面向对象的三大特性 面向对象编程,是许多编程语言都支持的一种编程思想。 简单理解是:基于模板(类)去创建实体(对象),使用对象完成功能开发。 面向对象包含3大主要特性: 封装 封…...
Redis Stream 流的深度解析与实现高级消息队列【一万字】
详细介绍了 Redis 5.0 版本新增加的数据结构Stream的使用方式以及原理,如何实现更加可靠的消息队列。 文章目录 Stream 概述2 Stream基本结构3 存储数据3.1 Entry ID3.2 数量限制 4 获取数据4.1 范围查询4.2 独立消费消息4.2.1 非阻塞使用4.2.2 阻塞的使用 4.3 消费…...
一个灵活、现代的Android应用架构
一个灵活、现代的Android应用架构 学习Android架构的原则:学习原则,不要盲目遵循规则。 本文旨在通过示例演示实际应用:通过示范Android架构来进行教学。最重要的是,这意味着展示出如何做出各种架构决策。在某些情况下࿰…...
redis高级篇 springboot+redis+bloomfilter实现过滤案例
一 bloomfilter的作用 1.1 作用 Bloomfilter:默认是有0组成bit数组和hash函数构成的数据结构,用来判断在海量数据中是否存在某个元素。 应用案例:解决缓存穿透。Bloomfilter放在redis前面,如果查询bf中没有则直接返回ÿ…...
mybatis学习笔记之在WEB中应用MyBatis
文章目录 数据库表的设计和准备数据环境搭建前端页面编写后端代码实现后端代码目录dao层servicewebpojoUtils 数据库表的设计和准备数据 环境搭建 在pom.xml中配置依赖(logback、mybatis、mysql、servlet) 注意引入tomcat 前端页面编写 <!DOCTYPE …...
宿主可以访问公网 Docker容器里无法访问 Temporary failure in name resolution
宿主可以访问公网 Docker容器里无法访问 Temporary failure in name resolution 容器参数 docker-compose.yml 的 dns我也设置,按理来说应该可以访问,然而就是不断的按在地上摩擦 web:build: .restart: alwaysports:- "6699:80"dns:- 114.11…...
CentOS7系统MBR、GRUB2、内核启动流程报错问题
目录 🥩Linux启动流程 🥩MBR修复 🍭1、模拟损坏 🍭2、重启测试 🍭3、修复MBR 🍭4、测试系统 🥩GRUB2修复 🍭1、模拟损坏 🍭2、修复GRUB2 🍭3、测试系统 &…...
剑指YOLOv5改进最新MPDIoU损失函数(23年7月首发论文):超越现有多种G/D/C/EIoU,高效准确的边界框回归的损失,高效涨点
💡本篇内容:剑指YOLOv5改进最新MPDIoU损失函数(23年7月首发论文):超越现有多种G/D/C/EIoU,高效准确的边界框回归的损失,高效涨点 💡🚀🚀🚀本博客 改进源代码改进 适用于 YOLOv5 按步骤操作运行改进后的代码即可 💡:重点:该专栏《剑指YOLOv5原创改进》只更新…...
CAN bus off ——ISO11898
什么是can bus off? CAN总线关闭(CAN bus off)是指CAN节点进入一种错误状态,无法继续正常的数据通信。当一个CAN节点的错误计数器超过了设定的阈值时,该节点将进入CAN总线关闭状态。在这种状态下,该节点将停…...
如何评测一个大语言模型?
编者按:大型语言模型(Large language models, LLMs)因其在学术界和工业界展现出前所未有的性能而备受青睐。随着 LLMs 在研究和实际应用中被广泛使用,对其进行有效评测变得愈发重要。近期已有多篇论文围绕大模型的评测进行研究&am…...
React中useMemo和useCallback的区别
一句话来解释,useMemo是缓存值的,useCallback是缓存函数的。 一、useMemo: 接收两个参数,第一个参数是个函数,第二个是依赖项。返回一个memoized值,只有当它的某个依赖项改变时才重新计算 memoized 值&…...
在WinForms里用OpenTK+SkiaSharp画个会动的波形图(.NET 8环境保姆级教程)
在WinForms里用OpenTKSkiaSharp画个会动的波形图(.NET 8环境保姆级教程) 最近在开发一个实时音频分析工具时,遇到了一个有趣的挑战:如何在Windows Forms应用中高效渲染动态波形图。经过多次尝试,我发现结合OpenTK的Ope…...
OpenClaw+千问3.5-9B:个人数字资产管理自动化系统
OpenClaw千问3.5-9B:个人数字资产管理自动化系统 1. 为什么需要个人数字资产管理 我的电脑桌面常年堆满截图、临时下载的PDF和来路不明的压缩包。上周找一份三个月前的会议记录时,不得不在十几个名为"新建文件夹(1)"的目录里大海捞针。这种混…...
终极指南:MoCo性能基准测试揭秘,ImageNet上67.5%准确率如何实现
终极指南:MoCo性能基准测试揭秘,ImageNet上67.5%准确率如何实现 【免费下载链接】moco PyTorch implementation of MoCo: https://arxiv.org/abs/1911.05722 项目地址: https://gitcode.com/gh_mirrors/mo/moco MoCo(Momentum Contras…...
MongoDB GridFS中出现大小为0的文件记录是怎么回事
files集合有记录但chunks为空,最常见原因是文件写入中途失败,导致仅插入files文档而未写入任何chunks。为什么 files 集合里有记录但 chunks 为空?这是最常见原因:文件写入中途失败,导致只插入了 files 文档࿰…...
安装The Agency后Opencode启动报错:Failed to parse YAML frontmatter: incomplete explicit mapping pair
报错:opencode Failed to parse frontmatter in /home/skywalk/opencodework/.opencode/agent/zk-steward.md: Failed to parse YAML frontmatter: incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line at line 3,…...
Visio是什么?附安装使用全流程
Visio是什么? 它是微软出品的专业图表绘制工具,是Office家族里最低调、但也是职场进阶最硬核的成员之一。如果说Excel是处理数字的神,那Visio就是处理逻辑和流程的王者。 安装教程和安装包获取 为什么建议你试试Visio? 1. 拖拽…...
告别对账熬夜,Captain AI帮你揪出Ozon的异常扣费
做Ozon的卖家,几乎都有过这样的经历:月底打开平台账单,密密麻麻全是俄语专业术语,看半天也看不懂每一笔钱扣在了哪里;熬一整个通宵核对账单,却还是算不清每一笔收支,找不到平台多扣的钱…...
并发编程模式(如生产者-消费者、任务分区、发布-订阅等)可以帮助我们更好地组织多线程代码,提高可维护性、性能和健壮性
基于之前的线程同步优化代码,我将进一步引入并发编程模式,以更结构化和可扩展的方式优化加热控制逻辑。并发编程模式(如生产者-消费者、任务分区、发布-订阅等)可以帮助我们更好地组织多线程代码,提高可维护性、性能和健壮性。 在加热控制场景中,适合的模式包括任务分区…...
项目性能优化实践:深入FMP算法原理探索
在技术领域,我们常常被那些闪耀的、可见的成果所吸引。今天,这个焦点无疑是大语言模型技术。它们的流畅对话、惊人的创造力,让我们得以一窥未来的轮廓。然而,作为在企业一线构建、部署和维护复杂系统的实践者,我们深知…...
PyTesseract实战:从参数调优到场景化OCR识别方案
1. PyTesseract入门:为什么参数调优如此重要? 第一次用PyTesseract做OCR识别时,我对着满屏乱码的输出结果差点崩溃——明明图片上的文字清晰可见,为什么识别结果却错得离谱?后来才发现,默认参数配置就像用菜…...
