当前位置: 首页 > news >正文

spring异步框架使用教程

背景

在需求开发过程中,为了提升效率,很容易就会遇到需要使用多线程的场景。这个时候一般都会选择建一个线程池去专门用来进行某一类动作,这种任务到来的时候往往伴随着大量的线程被创建调用。而还有另外一种场景是整个任务的执行耗时比较长,但又不适合起多线程去运行,只能后台起一个异步线程去慢慢跑。这个时候就需要一个公共的线程池。

可选方案

总体思想就是要有一个全局可用的线程池,可以用来执行一些零散的任务。

方案一

自定义一个全局的线程池,需要异步操作的就调用。这种方法好处是实现简单,并且调用起来也简单,直接当成一个方法就可以了。但需要同模块项目(或者导入了模块)才能使用。

方案二

使用Spring自带的注解@Async实现异步。这种方法的好处是注解可以跨模块使用,因为线程池对象会被注入容器,整个服务共用。而且更大的好处是使用简单,使用者只需要给所需异步操作的方法加上@Async(“beanName”)即可。其中beanName是指注入容器的对象的名称,也可以不加参数,不加参数代表使用默认线程池。

考虑到便捷性和新手友好性,选择了方案二。

实现(注意看我的调用的结构,可以避免循环依赖)

controller->async->service √
controller->service->async->service ×,这样会出现循环依赖

1.创建线程池配置类

/**
*	必须加上@EnableAsync注解
*/
@EnableAsync
@Configuration
public class TaskPoolConfig {/***	可以多创建几个bean注入容器,根据bean不同用来执行不同类型的任务*/@Bean("taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();//核心线程池大小executor.setCorePoolSize(16);//最大线程数executor.setMaxPoolSize(20);//配置队列容量,默认值为Integer.MAX_VALUEexecutor.setQueueCapacity(99999);//活跃时间executor.setKeepAliveSeconds(60);//线程名字前缀executor.setThreadNamePrefix("asyncServiceExecutor -");//设置此执行程序应该在关闭时阻止的最大秒数,以便在容器的其余部分继续关闭之前等待剩余的任务完成他们的执行executor.setAwaitTerminationSeconds(60);//等待所有的任务结束后再关闭线程池executor.setWaitForTasksToCompleteOnShutdown(true);return executor;}@Bean("taskExecutor2")public Executor taskExecutor2() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();//核心线程池大小executor.setCorePoolSize(16);//最大线程数executor.setMaxPoolSize(20);//配置队列容量,默认值为Integer.MAX_VALUEexecutor.setQueueCapacity(99999);//活跃时间executor.setKeepAliveSeconds(60);//线程名字前缀executor.setThreadNamePrefix("asyncServiceExecutor -");//设置此执行程序应该在关闭时阻止的最大秒数,以便在容器的其余部分继续关闭之前等待剩余的任务完成他们的执行executor.setAwaitTerminationSeconds(60);//等待所有的任务结束后再关闭线程池executor.setWaitForTasksToCompleteOnShutdown(true);return executor;}
}

2.使用异步

异步类:

public interface AsyncService {void test();
}
@Slf4j
@Service
public class AsyncServiceImpl implements AsyncService {@Autowiredprivate TestService testService;//这里的参数是只bean的名称,不填则使用默认的线程池。如果这个注解放在类上,代表这个类里面的全部方法都走异步@Async("taskExecutor")void test(){testService.todo();}@Async("taskExecutor2")void test2(){testService.todo2();}
}

业务类:

public interface TestService {void todo();void todo2();
}
@Slf4j
@Service
public class TestServiceImpl implements TestService{void todo(){LocalDateTime dateTime=LocalDateTime.now();log.info("已经进入异步方法,现在时间:{},睡三秒",dateTime);try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}dateTime=LocalDateTime.now();log.info("三秒后时间为:{}",dateTime);}void todo2(){}
}

测试类:

@Slf4j
@RestController
public class TestController {@Autowiredprivate AsyncService asyncService;@RequestMapping("/test")public void test(){asyncService.test();LocalDateTime dateTime=LocalDateTime.now();log.info("这是主线程,现在时间为:{}",dateTime);}
}

结果:成功
在这里插入图片描述

坑点

1.异步失效

如果一个类里面有两个方法A、B,方法B添加了异步注解,方法A调用方法B,异步不会生效。
查了一下,好像是因为异步注解的实现用到了动态代理,而一个类内部方法的调用不会走代理,也就没法实现异步。
因此,建议把异步都放在一个专门的异步类里面,这个类的方法只用来实现异步,方法内部再去调用真正的业务逻辑方法。

2.循环依赖

正常来说,A类中注入B类对象,B类中再注入A类对象。这种情况在代码中并不会发生循环依赖。而在异步注解中会出现循环依赖,因为异步注解底层实现用的是动态代理。

相关文章:

spring异步框架使用教程

背景 在需求开发过程中,为了提升效率,很容易就会遇到需要使用多线程的场景。这个时候一般都会选择建一个线程池去专门用来进行某一类动作,这种任务到来的时候往往伴随着大量的线程被创建调用。而还有另外一种场景是整个任务的执行耗时比较长…...

【数学建模】清风数模正课3 插值算法

插值算法 在数模比赛中,很多类型的题目都需要根据已知的函数点进行数据分析和模型处理; 当此时题目所给的数据较少时,我们就无法进行准确科学的分析,所以需要更多的数据,也就是函数点; 这就需要使用数学…...

什么是eval()?eval是用来干什么的?

一、什么是eval()? eval() 是 JavaScript 中的一个全局函数,用于解析并执行传递给它的字符串作为 JavaScript 代码。 二、eval()是用来干什么的? 当调用 eval() 时,它会将传入的字符串参数视为 JavaScript 代码,并在调用位置执…...

JavaScript-console:JavaScript控制台(Console)常用方法

一、理解 console JavaScript 控制台(console)是一个开发人员在编写 JavaScript 代码时常用的工具。它是浏览器提供的一种界面,让开发人员能够追踪代码执行的状态和结果。JavaScript 控制台可以记录代码输出的信息、警告和错误,并…...

Nginx配置前后端分离

后端地址 1.本地环境 curl --request GET \--url http://localhost:8080/by-admin/captchaImage \--header Authorization: Bearer d7a035d9-b30c-4ca5-8951-8cec90607943确认后端 ip 端口 上下文 2.测试环境 部署到测试环境可能是 换成内网ip和内网服务端口(ip、端口 可能会…...

rabbitmq的发布确认

生产者将信道设置成 confirm 模式,一旦信道进入 confirm 模式, 所有在该信道上面发布的 消息都将会被指派一个唯一的 ID (从 1 开始),一旦消息被投递到所有匹配的队列之后,broker 就会发送一个确认给生产者(包含消息的唯一 ID)&…...

RISC-V公测平台发布· CoreMark测试报告

一. CoreMark简介 CoreMark是一款用于评估CPU性能的基准测试程序,它包含了多种不同的计算任务,包括浮点数、整数、缓存、内存等方面的测试。CoreMark的测试结果通常被用来作为CPU性能的参考,它可以帮助开发人员和系统管理员评估不同处理器和…...

模型微调(fine-tune)

一、关于模型微调的一些基础知识 1、模型微调(fine-tune) 微调(fine-tune)通过使用在大数据上得到的预训练好的模型来初始化自己的模型权重,从而提升精度。这就要求预训练模型质量要有保证。微调通常速度更快、精度更高。当然,自己…...

云农场种植:互联网+智慧牧场,为农业注入新的活力和创新

随着科技的不断发展,数字化农业正逐渐成为现代农业的趋势。传统农业面临着土地资源有限、劳动力不足等问题,而云农场种植模式通过数字化技术的运用,互联网养殖着重于“绿色、特色产品和智慧生态”,通过建立“线上养殖线下托养线上…...

Hadoop学习一(初识大数据)

目录 一 什么是大数据? 二 大数据特征 三 分布式计算 四 Hadoop是什么? 五 Hadoop发展及版本 六 为什么要使用Hadoop 七 Hadoop vs. RDBMS 八 Hadoop生态圈 九 Hadoop架构 一 什么是大数据? 大数据是指无法在一定时间内用常规软件工具对其内…...

linux定时备份MySQL数据库循环删除前30天的备份文件

linux定时备份MySQL数据库循环删除前30天的备份文件 一、 检查有没安装crond,如果没有,先安装 1、先检查一下有没有cron rpm -qa|grep cron如果输入上面命令有如下显示,则不需要安装 2、没有安装的话,就使用一下命令安装 yum -y install …...

不加电透明屏:在场景化应用中,有哪些特点和优点?

不加电透明屏是一种新型的显示技术,它可以在不需要电源的情况下显示图像和文字。 这种屏幕的原理是利用光的折射和反射来实现显示效果,而不需要通过电流来激发像素点。 不加电透明屏的最大优点是节能环保。传统的显示屏需要消耗大量的电能来显示图像&a…...

全球公链进展| Shibarium已上线;opBNB测试网PreContract硬分叉;Sui 主网 V1.7.1 版本

01 ETH 以太坊最新一次核心开发者执行会议:讨论 Devnet 8 更新、ElP-4788、Holesky 测试网等 以太坊核心开发者 Tim Beiko 总结最新一次以太坊核心开发者执行会议(ACDE),讨论内容包括 Devnet 8 更新、ElP-4788、Holesky 测试网、…...

CSS中的display属性有哪些值?它们的作用?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ CSS display 属性的不同取值和作用1. block2. inline3. inline-block4. none5. flex6. grid7. table、table-row、table-cell8. list-item9. inline-table、table-caption、table-column 等 ⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#x…...

ELKstack-日志收集案例

由于实验环境限制,将 filebeat 和 logstash 部署在 tomcat-server-nodeX,将 redis 和 写 ES 集群的 logstash 部署在 redis-server,将 HAproxy 和 Keepalived 部署在 tomcat-server-nodeX。将 Kibana 部署在 ES 集群主机。 环境:…...

基于GPT-4和LangChain构建云端定制化PDF知识库AI聊天机器人

参考: GitHub - mayooear/gpt4-pdf-chatbot-langchain: GPT4 & LangChain Chatbot for large PDF docs 1.摘要: 使用新的GPT-4 api为多个大型PDF文件构建chatGPT聊天机器人。 使用的技术栈包括LangChain, Pinecone, Typescript, Openai和Next.js…...

Python可视化工具分享

今天和大家分享几个实用的纯python构建可视化界面服务,比如日常写了脚本但是不希望给别人代码,可以利用这些包快速构建好看的界面作为服务提供他人使用。有关于库的最新更新时间和当前star数量。 streamlit (23.3k Updated 2 hours ago) Streamlit 可让…...

ethers.js:构建ERC-20代币交易的不同方法

在这篇文章中,我们将探讨如何使用ethers.js将ERC-20令牌从一个地址转移到另一个地址 Ethers是一个非常酷的JavaScript库,它能够发送EIP-1559事务,而无需手动指定气体属性。它将确定gasLimit,并默认使用1.5 Gwei的maxPriorityFeePerGas,从v5.6.0开始。 此外,如果您使用签名…...

[实践篇]13.23 QNX环境变量profile

一,profile简介 /etc/profile或/system/etc/profile是qnx侧的设置环境变量的文件,该文件适用于所有用户,它可以用作以下情形: 设置HOMENAME和SYSNAME环境变量设置PATH环境变量设置TMPDIR环境变量(/tmp)设置PCI以及IFS_BASE等环境变量等文件内容示例如下: /etc/profile…...

HDLBits-Verilog学习记录 | Getting Started

Getting Started problem: Build a circuit with no inputs and one output. That output should always drive 1 (or logic high). 答案不唯一,仅共参考: module top_module( output one );// Insert your code hereassign one 1;endmodule相关解释…...

基于Sovereign-MCP-Servers构建私有AI工具链:从协议原理到Docker化部署

1. 项目概述与核心价值最近在折腾AI应用开发,特别是想给Claude、Cursor这类工具加上“联网”和“执行”能力时,绕不开一个概念:MCP(Model Context Protocol)。简单说,MCP就是一套标准协议,它能让…...

避坑指南:在Unity 2022 LTS中配置XCharts插件时遇到的3个常见问题及解决方法

Unity 2022 LTS中XCharts插件实战避坑手册 当数据可视化成为现代应用的核心需求时,Unity开发者常会选择XCharts这类开源图表插件来快速实现专业级图表展示。但在实际项目落地过程中,版本兼容性、环境配置和平台适配等问题往往会让开发进程意外卡壳。本文…...

React轻量级代码编辑器组件:基于Textarea的语法高亮方案

1. 项目概述:一个为React开发者量身打造的代码编辑器组件 如果你在React项目中需要嵌入一个代码编辑器,并且希望它轻量、美观、开箱即用,那么 uiwjs/react-textarea-code-editor 这个组件库很可能就是你一直在寻找的解决方案。它不是一个像…...

CC2530与ESP8266物联网网关:ZigBee转Wi-Fi通信协议转换实战

1. 项目概述:当ZigBee遇上Wi-Fi最近在折腾一个智能家居的传感器节点,核心是TI的CC2530 ZigBee芯片。这玩意儿功耗低、组网方便,是很多低功耗传感网络的绝佳选择。但问题来了,ZigBee网络的数据最终怎么方便地送到我们手机上去看呢&…...

微服务架构实战:从DDD设计到K8s部署的完整指南

1. 项目概述与核心价值最近几年,微服务架构的热度一直居高不下,从互联网大厂到初创团队,几乎人人都在谈微服务。但说实话,真正能把微服务玩转、落地,并且能稳定支撑业务发展的团队,其实并不多。很多项目要么…...

2026年冰袋吸水粉厂家大揭秘:选择指南与行业趋势题

随着冷链物流行业的快速发展,冰袋吸水粉作为冷链运输中不可或缺的保冷材料,其市场需求持续增长。然而,市场上冰袋吸水粉的质量参差不齐,如何选择一家值得信赖的厂家成为许多采购商关注的重点。本文将从行业背景、技术特点及市场趋…...

ctfileGet:城通网盘直连地址解析工具的技术原理与实用指南

ctfileGet:城通网盘直连地址解析工具的技术原理与实用指南 【免费下载链接】ctfileGet 获取城通网盘一次性直连地址 项目地址: https://gitcode.com/gh_mirrors/ct/ctfileGet ctfileGet是一个基于Web的开源工具,专门用于解析城通网盘分享链接并获…...

Claude API密钥自动化同步工具:架构设计与实战部署指南

1. 项目概述与核心价值最近在折腾一个挺有意思的自动化项目,起因是我发现团队里不同成员在使用Claude API时,经常遇到一个挺烦人的问题:每个人手里的API密钥状态不一致。有的同事的密钥突然失效了,有的配额用完了自己还不知道&…...

编写程序统计婚恋交友消费,相处长处度数据,分析理性婚恋模式,减少年轻人恋爱高频无谓消费。

构建一个婚恋交友消费与相处时长统计分析、理性婚恋模式识别的商务智能示例项目,去营销化、中立化,仅用于学习与工程实践参考。一、实际应用场景描述在当代年轻人的婚恋与社交生活中,存在一种普遍现象:- 约会高度依赖“消费型场景…...

Node.js后端服务快速集成Taotoken,为应用注入大模型能力

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Node.js后端服务快速集成Taotoken,为应用注入大模型能力 为Node.js后端服务添加大模型能力,可以显著提升应…...