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

@Async 异步注解使用

@Async 异步注解使用

使用版本SpringBoot-2.7.18

使用@EnableAsync开启异步注解
@EnableAsync
@SpringBootApplication
public class TestApplication {public static void main(String[] args) {SpringApplication.run(TestApplication.class, args);}}
在需要的方法上加上@Async
@Service
public class TestServiceImpl implements TestService {@Override@Asyncpublic LocalDateTime async() {return LocalDateTime.now();}
}
Spring Boot使用的异步任务执行器
默认情况异步任务执行器使用ThreadPoolTaskExecutor

org.springframework.aop.interceptor.AsyncExecutionInterceptor.invoke() 方法中打断点可以看到使用的是哪个线程池

@Override
@Nullable
public Object invoke(final MethodInvocation invocation) throws Throwable {Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);Method specificMethod = ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);final Method userDeclaredMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);//1、这里打个断点可以看到使用的是哪个线程池AsyncTaskExecutor executor = determineAsyncExecutor(userDeclaredMethod);if (executor == null) {throw new IllegalStateException("No executor specified and no default executor set on AsyncExecutionInterceptor either");}Callable<Object> task = () -> {try {Object result = invocation.proceed();if (result instanceof Future) {return ((Future<?>) result).get();}}catch (ExecutionException ex) {handleError(ex.getCause(), userDeclaredMethod, invocation.getArguments());}catch (Throwable ex) {handleError(ex, userDeclaredMethod, invocation.getArguments());}return null;};return doSubmit(task, executor, invocation.getMethod().getReturnType());
}
直接配置一个异步任务执行器,使用@Async注解,异步任务执行器会更改成 myTaskExecutorA
@Configuration
public class BeanConfigure {@BeanTaskExecutor myTaskExecutorA() {return new MyTaskExecutorA();}public static class MyTaskExecutorA implements TaskExecutor {@Overridepublic void execute(Runnable task) {System.err.println("==========》" + task.getClass());}}
}
恰巧我们配置了两个异步任务执行器,会切换使用 org.springframework.core.task.SimpleAsyncTaskExecutor
@Configuration
public class BeanConfigure {@BeanTaskExecutor myTaskExecutorA() {return new MyTaskExecutorA();}@BeanTaskExecutor myTaskExecutorB() {return new MyTaskExecutorB();}public static class MyTaskExecutorA implements TaskExecutor {@Overridepublic void execute(Runnable task) {System.err.println("==========》" + task.getClass());}}public static class MyTaskExecutorB implements TaskExecutor {@Overridepublic void execute(Runnable task) {System.err.println("==========》" + task.getClass());}}
}

首先, org.springframework.core.task.SimpleAsyncTaskExecutor执行效果不是很好;其次,项目中的其他业务可能会配置使用多于两个的TaskExecutor,所以使用@Async的最佳实践是为其明确指定异步任务执行器:@Async(“myTaskExecutorA”)

@Service
public class TestServiceImpl implements TestService {@Override@Async("myTaskExecutorA")//明确指定需要使用的异步执行器public LocalDateTime async() {return LocalDateTime.now();}
}

相关文章:

  • 基于YOLOv10深度学习的草莓成熟度检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、人工智能
  • C# VideoCapture 多路视频播放
  • uniapp粘贴板地址识别 address-parse插件的使用
  • 20240810在荣品RK3588S-AHD开发板的预置Android13下挂载exFAT的256GB的TF卡
  • 十二、OpenCVSharp 中的图像匹配与模板匹配
  • buildroot是啥,用来干什么?怎么用
  • ImportError: DLL load failed: 找不到指定的程序的解决方案
  • GLM4 API 调用方法
  • CH07_数据绑定
  • 电子电气架构 --- 座舱域控制器:一芯多屏快速渗透
  • 【定稿】英飞凌Aurix2G TC3XX CAN模块详解
  • extern在头文件中添加是否必要?(C/C++)
  • 怎么衡量数据仓库模型的优与劣
  • 电池常用,但电芯热电耦合难?科学仿真技术轻松解决
  • 接口优化笔记
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • IndexedDB
  • iOS 系统授权开发
  • js ES6 求数组的交集,并集,还有差集
  • php的插入排序,通过双层for循环
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • Python实现BT种子转化为磁力链接【实战】
  • rc-form之最单纯情况
  • Twitter赢在开放,三年创造奇迹
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • 编写符合Python风格的对象
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 聊聊flink的TableFactory
  • 前端面试之CSS3新特性
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 微信小程序:实现悬浮返回和分享按钮
  • ​2021半年盘点,不想你错过的重磅新书
  • ​TypeScript都不会用,也敢说会前端?
  • # Redis 入门到精通(九)-- 主从复制(1)
  • #mysql 8.0 踩坑日记
  • #我与Java虚拟机的故事#连载04:一本让自己没面子的书
  • (0)Nginx 功能特性
  • (C语言)共用体union的用法举例
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (离散数学)逻辑连接词
  • (十六)串口UART
  • (四十一)大数据实战——spark的yarn模式生产环境部署
  • (算法)区间调度问题
  • (转)mysql使用Navicat 导出和导入数据库
  • .apk文件,IIS不支持下载解决
  • .NET 4.0中的泛型协变和反变
  • .net Stream篇(六)
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .NET分布式缓存Memcached从入门到实战
  • .net下的富文本编辑器FCKeditor的配置方法
  • [ vulhub漏洞复现篇 ] GhostScript 沙箱绕过(任意命令执行)漏洞CVE-2019-6116
  • [BZOJ3757] 苹果树
  • [C#]使用C#部署yolov8-seg的实例分割的tensorrt模型