使用Spring中@Async注解实现异步调用
异步调用?
在解释异步调用之前,我们先来看同步调用的定义;同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果。 异步调用则是只是发送了调用的指令,调用者无需等待被调用的方法完全执行完毕,继续执行下面的流程。例如, 在某个调用中,需要顺序调用 A, B, C三个过程方法;如他们都是同步调用,则需要将他们都顺序执行完毕之后,过程才执行完毕; 如B为一个异步的调用方法,则在执行完A之后,调用B,并不等待B完成,而是执行开始调用C,待C执行完毕之后,就意味着这个过程执行完毕了。
概述说明
Spring中通过任务执行器(TaskExecutor)来实现多线程和并发编程。使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExcutor。而实际开发中任务一般是异步的,我们可以在配置类中通过@EnableAsync开启对异步任务的支持,并通过在实际执行的Bean的方法中使用@Async注解来声明其是一个异步任务。
从Spring3开始提供了@Async注解,该注解可以被标注在方法上,以便异步地调用该方法。调用者将在调用时先返回结果标志,方法的实际执行将提交给Spring TaskExecutor的任务中,由指定的线程池中的线程执行。
@Async应用自定义线程池
配置类
/**
* @author 佛大Java程序员
* @since 1.0.0
*/
@Configuration
@ComponentScan("com.whl.asyncdemo")
@EnableAsync
public class TaskExecutorConfig implements AsyncConfigurer { @Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
} @Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
说明:
* 利用@EnableAsync 注解开启异步任务支持
* 自定义线程池需要定义的配置类中实现AsyncConfigurer接口并重写getAsyncExecutor(),返回一个ThreadPoolTaskExecutor,这样我们就获得了一个基于线程池的TaskExecutor
执行类
/**
* @author 佛大Java程序员
* @since 1.0.0
*/
@Service
public class AsyncTaskService { @Async
public void executeAsyncTask(Integer i){
System.out.println("执行异步任务1:" + i);
} @Async
public void executeAsyncTaskPlus(Integer i){
System.out.println("执行异步任务2 " +(i+1));
}
}
说明:
@Async注解表明方法是个异步方法,如果注解在类级别,则表明该类所有的方法都是异步方法,而这里的方法自动注入使用ThreadPoolTaskExecutor作为TaskExecutor。
测试类
/**
* @author 佛大Java程序员
* @since 1.0.0
*/
public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskExecutorConfig.class);
AsyncTaskService asyncTaskService = context.getBean(AsyncTaskService.class); for (int i = 0; i < 5 ; i++) {
asyncTaskService.executeAsyncTask(i);
asyncTaskService.executeAsyncTaskPlus(i);
} //校验异步方法是否先返回结果值
System.out.println("返回执行成功,验证异步是否先返回结果值");
context.close(); }
}
执行结果
注释@Async
放开@Async注释
@Async应用默认线程池
待补充
@Async调用中的事务处理机制?
在@Async标注的方法,同时也适用了@Transactional进行了标注;在其调用数据库操作之时,将无法产生事务管理的控制,原因就在于其是基于异步处理的操作。那该如何给这些操作添加事务管理呢?可以将需要事务管理操作的方法放置到异步方法内部,在内部被调用的方法上添加@Transactional.
(1) 使用了@Async/@Transactional来标注,但是无法产生事务控制的目的。
(2) 使用了@Async来标注, B中调用了C、D,C/D分别使用@Transactional做了标注,则可实现事务控制的目的。
项目实战
WKD项目里面使用Easypoi技术来导出Excel,导出数据量数据量不大的时候用同步导出也没事,但是对于数据量大且需要导出的数据封装业务较复杂,就会出现应用OOM或者出现响应超时。为了解决此问题,通过用线程池异步导出的方式实现。
参考/好文:
书籍 -- SpringBoot实战 -- 汪云飞 编著
使用Spring中@Async注解实现异步调用的更多相关文章
- Spring中@Async注解实现“方法”的异步调用
原文:http://www.cnblogs.com/zhengbin/p/6104502.html 简单介绍: Spring为任务调度与异步方法执行提供了注解支持.通过在方法上设置@Async注解,可 ...
- Spring源码学习之:@async 方法上添加该注解实现异步调用的原理
在我们使用spring框架的过程中,在很多时候我们会使用@async注解来异步执行某一些方法,提高系统的执行效率.今天我们来探讨下 spring 是如何完成这个功能的. spring 在扫描be ...
- Spring @async 方法上添加该注解实现异步调用的原理
Spring @async 方法上添加该注解实现异步调用的原理 学习了:https://www.cnblogs.com/shangxiaofei/p/6211367.html 使用异步方法进行方法调用 ...
- @async 方法上添加该注解实现异步调用的原理
在我们使用spring框架的过程中,在很多时候我们会使用@async注解来异步执行某一些方法,提高系统的执行效率.今天我们来探讨下 spring 是如何完成这个功能的. spring 在扫描bean的 ...
- SpringBoot系列——@Async优雅的异步调用
前言 众所周知,java的代码是同步顺序执行,当我们需要执行异步操作时我们需要创建一个新线程去执行,以往我们是这样操作的: /** * 任务类 */ class Task implements Run ...
- Spring中@Async用法详解及简单实例
Spring中@Async用法 引言: 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类 ...
- SpringCloud 微服务中 @Async 注解自定义线程池 引发的aop 问题
背景 在 使用springCloud 的@Async注解来做异步操作时,想自定义其线程池. 引发问题 自定义完线程池后,发现代码里并没有使用自定义线程池里的线程,于是新建一个demo工程,一样的配置代 ...
- 【转】Spring中@Async
Spring中@Async 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实, ...
- 全面解析Spring中@ModelAttribute注解的用法
本文不再更新,可能存在内容过时的情况,实时更新请移步我的新博客:全面解析Spring中@ModelAttribute注解的用法: @ModelAttribute注解用于将方法的参数或方法的返回值绑定到 ...
随机推荐
- 【软件测试部署基础】gradle的认识
1. gradle简介 Java世界中主要有三大构建工具:Ant.Maven和Gradle.经过几年的发展,Ant几乎销声匿迹.Maven也日薄西山,而Gradle的发展则如日中天. 1.1. ANT ...
- go中位运算
左移右移 const ( // 将 1 左移 100 位来创建一个非常大的数字 // 即这个数的二进制是 1 后面跟着 100 个 0 Big = 1 << 100 // 再往右移 99 ...
- 自学linux——22.粘滞位的了解及使用
粘滞位的了解及使用 一.权限 1.文件的权限 r (read) :可读取该文件的实际内容w(write):可以编辑,新增或者修改该文件的内容(但不含删除该文件)x(execute):代表该文件可以被系 ...
- js 转为整数之Number()、parseInt()、parseFloat()区别
一:Number() 如果是Boolean值,true和false值将分别被转换为1和0. 如果是数字值,只是简单的传入和返回. 如果是null值,返回0. 如果是undefined,返回NaN. 如 ...
- 落谷 P1410 子序列
题目链接. Discription 给定长度为 \(n\) 的序列 \(A\)(\(n\) 为偶数),判断是否能将其划分为两个长度为 \(\dfrac{N}{2}\) 的严格递增子序列. Soluti ...
- Robot Framework+adb框架自动化测试Android设备案例⑷——L2层关键字
一.EMMC测试套件 L2层关键字.robot *** Settings *** Resource ../L3公共层.robot *** Keywords *** 一般录影文件列表(EMMC) ${f ...
- 搭建docker registry私有镜像仓库
搭建docker registry私有镜像仓库 一.安装docker-distribution yum install -y docker-distribution 安装完成后,启动服务: syste ...
- STL——容器(Map & multimap)的大小
1. Map & multimap 的大小 map.size(); //返回容器中元素的数目 map.empty();//判断容器是否为空, 容器中有内容将会返回 false 代码示例 ...
- Consul的使用
Consul的使用 生产部署中,Consul安装在要注册服务的每个节点上.Consul有两种运行模式:客户端和服务器端,每个Consul数据中心必须至少有一个服务器,负责维护Consul状态,为了 ...
- Kafka Producer TimeoutException
基本需求 程序读取HDFS上的日志发送至Kafka集群 由于日志量较大 每小时约7亿条+ 采用多线程 多producer实例发送 TPS 可达到120W+ 修改前Producer配置 val prop ...