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 值&…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
