Spring Boot的@Async注解有哪些坑需要避免

一、什么是@Async注解?
@Async注解是Spring框架提供的一种用于声明异步方法的工具。它可以将标注的方法从调用者的线程中分离出来,另起一个新线程执行,从而避免阻塞调用者的线程,提高系统的并发能力和响应速度。
基本使用方法如下:

@Service
public class AsyncService {@Asyncpublic void asyncMethod() {// 异步任务逻辑}
}

在上述例子中,asyncMethod方法将在一个独立的线程中执行,不会阻塞调用它的主线程。

二、为什么会产生“坑”?
尽管@Async注解使用起来十分简单,但其背后的机制却涉及Spring的AOP(面向切面编程)和代理模式。这些机制在实际应用中容易导致一些意想不到的问题,即所谓的“坑”。这些“坑”通常源于对@Async注解的使用限制和Spring代理机制的不完全理解。

三、常见的“坑”及其规避方法

1. @Async只能作用于public方法
问题:@Async注解只对public方法有效,如果注解在private、protected或包级私有的方法上,将不会生效。
原因:这是因为Spring使用代理对象来处理异步调用,而代理对象只能代理public方法。
规避方法:确保所有标注@Async注解的方法是public的。
2. 自调用问题
问题:如果一个类中调用自身的异步方法,@Async注解将不会生效。
原因:这是因为Spring的代理机制,只有通过代理对象调用时注解才生效,而类内部的自调用不会经过代理对象。
规避方法:通过注入自身的代理对象来调用异步方法。

@Service
public class AsyncService {@Autowiredprivate AsyncService selfProxy;public void callerMethod() {selfProxy.asyncMethod();}@Asyncpublic void asyncMethod() {// 异步任务逻辑}
}

3. 配置线程池
问题:默认情况下,SpringBoot会使用一个简单的SimpleAsyncTaskExecutor,这个执行器不是真正的线程池,可能会导致性能问题。
原因:SimpleAsyncTaskExecutor每次调用时都会创建一个新线程,没有线程重用机制,可能导致大量线程创建和销毁的开销。
规避方法:自定义线程池并在@EnableAsync注解中指定。

@Configuration
@EnableAsync
public class AsyncConfig {@Bean(name = "taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(2);executor.setMaxPoolSize(5);executor.setQueueCapacity(500);executor.setThreadNamePrefix("AsyncThread-");executor.initialize();return executor;}
}

然后在使用@Async注解时指定这个线程池:

@Service
public class AsyncService {@Async("taskExecutor")public void asyncMethod() {// 异步任务逻辑}
}

4. 异步方法中的异常处理
问题:异步方法抛出的异常不会被直接捕获到,需要额外处理。
原因:异步方法在独立线程中执行,异常不会自动传递到调用线程。
规避方法:使用AsyncUncaughtExceptionHandler处理未捕获的异常。

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(2);executor.setMaxPoolSize(5);executor.setQueueCapacity(500);executor.setThreadNamePrefix("AsyncThread-");executor.initialize();return executor;}@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return new CustomAsyncExceptionHandler();}
}public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {@Overridepublic void handleUncaughtException(Throwable throwable, Method method, Object... obj) {System.out.println("Exception message - " + throwable.getMessage());System.out.println("Method name - " + method.getName());for (Object param : obj) {System.out.println("Parameter value - " + param);}}
}

5. 返回类型为Future
问题:如果异步方法的返回类型是Future或其子类,需要正确处理其结果。
原因:异步方法返回的Future对象需要调用get()方法获取结果,同时需要处理可能的异常。
规避方法:正确使用Future接口,处理异常并获取结果。

@Async
public Future<String> asyncMethodWithReturn() {// 异步任务逻辑return new AsyncResult<>("Result");
}public void callerMethod() {Future<String> future = asyncMethodWithReturn();try {String result = future.get();System.out.println(result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}
}

四、总结
SpringBoot的@Async注解为异步编程提供了极大的便利,但在使用时必须注意其背后的代理机制和具体实现细节。通过了解和规避上述常见的“坑”,开发者可以更高效地利用@Async注解,提高应用的并发性能和响应速度。在实际项目中,结合具体需求和环境,合理配置和使用异步任务,才能真正发挥其优势。

欢迎大家积极留言交流学习心得,点赞的人最美丽!

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

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

相关文章

Redis页面优化

文章目录 1.Redis页面缓存1.思路分析2.首先记录一下目前访问商品列表页的QPS1.线程组配置10000次请求2.请求配置3.开始压测1.压测第一次 平均QPS为6122.压测第二次 平均QPS为6153.压测第三次 平均QPS为617 3.然后记录一下访问商品详情页的QPS1.线程组配置10000次请求2.请求配置…

AIGC简介:如何利用人工智能进行内容生成

目录 一、引言二、AIGC的定义与技术原理1. 定义说明2. 关键技术3. 技术原理 三、AIGC的主要应用领域1. 文本内容生成2. 图像和视频生成3. 音频内容的创建4. 数据分析与报告 四、实施AIGC的步骤和方法1. 定义项目目标2. 数据准备与处理3. 选择合适的工具和技术4. 模型训练与测试…

uni-app学习--基础组件使用、页面生命周期、本地存储、网络请求、条件编译、路由跳转

文章目录 1. 基本组件的使用1. text文本组件的使用2. view视图容器组件的使用3. button按钮组件的使用4. image组件的使用5. map组件 2. uni-app中的样式1. uni-app&#xff1a;px2rpx计算 3. uni-app的数据绑定1. 基本的数据绑定2. v-bind,v-for,v-on 4. uni-app的生命周期1. …

服务器数据恢复—raid5阵列上分配的卷被删除后重建如何恢复被删除卷的数据?

服务器存储数据恢复环境&#xff1a; 某品牌FlexStorage P5730服务器存储&#xff0c;存储中有一组由24块硬盘组建的RAID5阵列&#xff0c;包括1块热备硬盘。 服务器存储故障&#xff1a; 存储中的2个卷被删除&#xff0c;删除之后重建了一个新卷。需要恢复之前删除的一个卷的数…

等保题目分享(60000字版)

文章目录 前言判断题单选题多选题简答题 前言 来源于网友会议 判断题 在对数据进行差异备份前&#xff0c;仍需进行数据库的全量备份。&#xff08;T) 某应用系统后台连续登录失败3次以后&#xff0c;需要输入验证码才能继续登录&#xff0c;这个应用系统实现了登录失败处理…

flink 状态

状态&#xff08;State&#xff09;是一个重要的概念&#xff0c;它允许Flink在处理流数据时跟踪和存储中间结果。这对于实现复杂的计算逻辑和满足应用需求至关重要。 Working with State 1. 状态类型 Flink支持两种主要类型的状态&#xff1a; 1.1 算子状态&#xff08;Op…

头文件和源文件的一些情况分析

c函数的定义和声明 函数和变量的声明可以有多次,但是定义只能有一次 其实头文件可以写函数的定义,但是在工程里面很多人引用这个头文件很容易造成重复定义的情况 有一个例外情况头文件里面也可以写函数定义或者变量定义 一般情况 //2.h #pragma once int add(int a, int b…

洛谷 P8721 [蓝桥杯 2020 省 AB3] 填空问题(缺少 inc.txt, E 题数据) 题解

题目分析 A 数青蛙 根据青蛙的个数分类计算&#xff1a; 青蛙数小于等于 2 2 2&#xff1a;此时青蛙数、眼睛数、嘴巴数和腿数读出来只读 1 1 1 个字&#xff0c;故此时一句话 14 14 14 个字。青蛙数大于 2 2 2&#xff0c;小于等于 5 5 5&#xff1a;此时青蛙数、眼睛…

百分之九十的人都忽视了JMeter响应断言中的这个实用功能—— Jmeter Variable Name to use

JMeter的响应断言 相信对于使用过JMeter的同学来学&#xff0c;一定都使用过响应断言&#xff0c;在这里我就不相信介绍了&#xff0c;我们可以简单的理解为&#xff1a; JMeter的响应断言是一种用于检查测试中得到的响应数据是否符合预期的工具&#xff0c;旨在保证性能测试…

最高100万!2024年成都市标杆场景项目申报条件对象、奖励和认定材料流程

一、申报条件 &#xff08;一&#xff09;申报主体需注册成立两年以上&#xff0c;具备独立法人资格&#xff0c;在成都有固定经营或者生产场地&#xff0c;上两年度主营业务收入年均1000万元以上或上两年度主营业务收入增长率年均10%以上&#xff1b; &#xff08;二&#x…

java基础选择题--18(转载)

1.设有定义 int a3 &#xff0c;b4&#xff0c;c5&#xff1b; 则以下的表达式中 &#xff0c; 值为 false 的是 &#xff08;&#xff09; 正确答案: D 你的答案&#xff1a;D&#xff08;正确&#xff09; A.a < b && b < c B.a < b C.a < ( b c ) D.!…

基于单片机的电流检测装置

摘  要 : 随着电子技术的发展和进步 , 小信号在电路中的使用愈加广泛 , 在实际应用中对于小电流信号的采集和监控越来越重要。 因此电路中的电流需要能够被简单 、 方便 、 准确 、 实时地测量 。 文中设计并实现了一套基于单片机的电流检测系统。 该系统使用功率放大电路…

2024最新python入门教程|python安装|pycharm安装

前言&#xff1a;在安装PyCharm之前&#xff0c;首先需要明确PyCharm是一款功能强大的Python集成开发环境&#xff08;IDE&#xff09;&#xff0c;由JetBrains公司开发。PyCharm旨在通过提供智能代码补全、语法高亮、代码检查、快速导航和重构等丰富的编码辅助工具&#xff0c…

物联网的应用——工业自动化

工业自动化在物联网的应用主要体现在以下几个方面&#xff0c;这些应用不仅提高了工业生产的效率和质量&#xff0c;还优化了资源利用&#xff0c;降低了生产成本。以下是详细的分析和归纳&#xff1a; 数据采集与传输 物联网技术通过传感器实时采集工业设备的运行状态、温度、…

亚信安慧AntDB:全新的数据库体验

AntDB的核心设计理念是为了满足核心数据库升级改造的自主创新要求。它不仅提供了高效、可靠的数据处理能力&#xff0c;还特别强调了系统的可扩展性和前瞻性。这一设计理念奠定了AntDB在数据库领域的稳固地位&#xff0c;使其成为业内备受瞩目的技术创新之一通过采用最新的数据…

在无GPU的windows上运行ChatTTS

如果你在安装的过程中出现了下面的错误&#xff0c;不妨先看看这些安装步骤&#xff1a; cl: 命令行 error D8021 :无效的数值参数“/Wno-register” error: command C:\ windows ERROR: Failed building wheel for pynini 卷完了文本&#xff0c;卷图片&#xff0c;卷完了图…

dp和px的转化(dp2px,px2dp)

public class DensityUtil {/*** 根据手机的分辨率从 dp 的单位 转成为 px(像素).** param dpValue dpValue* return px*/public static int dp2px(float dpValue) {return (int) Math.ceil(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, dpValue, Resources.getSyst…

AI 入门指南二 :AI提示词(Prompt)

一&#xff0c;提示词的定义 提示词在中文中意为“触发”&#xff0c;在自然语言处理&#xff08;NLP&#xff09;的领域&#xff0c;它更接近于一个“心领神会”的概念&#xff0c;而非具有明确定义的术语。 简而言之&#xff0c;提示词是用户对大型语言模型的输入&#xff0…

Qt——Qt网络编程之TCP通信客户端的实现(使用QTcpSocket实现一个TCP客户端例程)

【系列专栏】:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! 《项目案例分享》 《极客DIY开源分享》 《嵌入式通用开发实战》 《C++语言开发基础总结》 《从0到1学习嵌入式Linux开发》 《QT开发实战》 《Android开发实战》

电脑自动关机怎么设置?简单3步就能搞定

电脑自动关机功能在许多场景下非常实用&#xff0c;例如下载大文件后自动关机、长时间不使用电脑后自动关机以节省能源等。通过合理设置自动关机&#xff0c;可以提高电脑使用的便利性和节能效果。本文将介绍电脑自动关机怎么设置的三种方法&#xff0c;帮助您根据不同需求灵活…