原来你是这样的SpringBoot--Async异步任务
本节我们一起学习一下SpringBoot中的异步调用,主要用于优化耗时较长的操作,提高系统性能和吞吐量。
一、新建项目,启动异步调用
首先给启动类增加注解@EnableAsync,支持异步调用
@EnableAsync
@SpringBootApplication
public class CathySpringbootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(CathySpringbootDemoApplication.class, args);
}
}
然后定义要执行的Task,分类增加一个同步方法和异步方法,其中异步方法需要增加注解@Async
@Component
public class AsyncTask {
/**
* 异步任务,需要注解@Async
*
* @param taskId 任务编号id
* @param second 执行时长,模拟慢任务
* @return
*/
@Async
public Future<Boolean> asyncExec(int taskId, Long second) {
exec(taskId, second);
return new AsyncResult<>(Boolean.TRUE);
}
public void exec(int taskId, Long second) {
System.out.println("开始执行任务" + taskId);
try {
Thread.sleep(second * 1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("结束执行任务" + taskId);
}
}
其实接下来就可以在controller中创建接口来进行简单的测试了
@RestController
@RequestMapping("/async")
public class AsyncController {
@Autowired
AsyncTask asyncTask;
@GetMapping("sync_task")
public String syncTask() {
long start = System.currentTimeMillis();
asyncTask.exec(1, 3L);
asyncTask.exec(2, 3L);
asyncTask.exec(3, 3L);
long time = System.currentTimeMillis() - start;
return "同步执行,耗时" + time;
}
@GetMapping("async_task")
public String asyncTask() {
long start = System.currentTimeMillis();
Future<Boolean> f1 = asyncTask.asyncExec(1, 3L);
Future<Boolean> f2 = asyncTask.asyncExec(2, 3L);
Future<Boolean> f3 = asyncTask.asyncExec(3, 3L);
try {
f1.get();
f2.get();
f3.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
long time = System.currentTimeMillis() - start;
return "异步执行,耗时" + time;
}
}
启动程序,查看接口响应结果:
http://localhost:16001/async/sync_task

http://localhost:16001/async/async_task

注意:异步方法和调用一定要写在不同的类中
二、线程池配置
上面的例子,在耗时服务多的情况下,使用异步方法确实提高了响应速度。但是它默认启用的是Spring默认的线程池SimpleAsyncTaskExecutor,不太灵活。我们把异步请求多增加几次调用看看效果:
@GetMapping("async_task")
public String asyncTask() {
long start = System.currentTimeMillis();
List<Future<Boolean>> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
Future<Boolean> fi = asyncTask.asyncExec(i, 10L);
list.add(fi);
}
for (int i = 0; i < 20; i++) {
list.forEach(x -> {
try {
x.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
});
}
long time = System.currentTimeMillis() - start;
return "异步执行,耗时" + time;
}

从上面的运行效果来看,一旦超过8个并行执行的任务,就开始出现等待了。
接下来,我们自定义线程池
@Bean
public TaskExecutor threadPoolTaskExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(8);
executor.setMaxPoolSize(16);
executor.setQueueCapacity(20);
executor.setKeepAliveSeconds(30);
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setThreadNamePrefix("task-thread-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
executor.initialize();
return executor;
}
然后在异步方法的注解中,明确指定所使用的线程池
@Async("threadPoolTaskExecutor")
public Future<Boolean> asyncExec(int taskId, Long second) {
exec(taskId, second);
return new AsyncResult<>(Boolean.TRUE);
}
执行效果如下:


可以看出,线程池设置的参数已经生效。
本人公众号[ 敬YES ]同步更新,欢迎大家关注~

原来你是这样的SpringBoot--Async异步任务的更多相关文章
- SpringBoot @Async 异步处理业务逻辑和发短信逻辑
有个业务场景,业务数据审核通过后需要给用户发短信,发短信过程比较耗时,可能需要几秒甚至十几秒,因此使用异步发短信 使用了注解@Async来实现: 1.SpringApplication启用注解@Ena ...
- springboot+async异步接口实现和调用
什么是异步调用? 异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步程序执行完即可执行. 如何实现异步调用? 多线程, ...
- springboot+@async异步线程池的配置及应用
示例: 1. 配置 @EnableAsync @Configuration public class TaskExecutorConfiguration { @Autowired private Ta ...
- @Async异步注解与SpringBoot结合使用
当你在service层需要启动异步线程去执行某些分支任务,又不希望显式使用Thread等线程相关类,只想专注于实现业务逻辑代码开发,可以使用@Async异步注解. 1. 使用@Async 异步注解 C ...
- SpringBoot中异步请求和异步调用(看这一篇就够了)
原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10661591.html,否则将追究法律责任!!! 一.SpringBoot中异步请求的使用 ...
- spring boot使用自定义配置的线程池执行Async异步任务
一.增加配置属性类 package com.chhliu.springboot.async.configuration; import org.springframework.boot.context ...
- SpringBoot:异步开发之异步调用
前言 除了异步请求,一般上我们用的比较多的应该是异步调用.通常在开发过程中,会遇到一个方法是和实际业务无关的,没有紧密性的.比如记录日志信息等业务.这个时候正常就是启一个新线程去做一些业务处理,让主线 ...
- Spring Boot -- Spring Boot之@Async异步调用、Mybatis、事务管理等
这一节将在上一节的基础上,继续深入学习Spring Boot相关知识,其中主要包括@Async异步调用,@Value自定义参数.Mybatis.事务管理等. 本节所使用的代码是在上一节项目代码中,继续 ...
- Springboot:异步业务处理(十二)
说明 当正常业务处理调用一个复杂业务或者耗时较长的请求时,客户等待时间会比较长,造成不好的用户体验,所以这时候需要用的异步处理 构建一个群发邮件的service接口及实现(模拟) 接口:com\spr ...
- SpringBoot使用异步线程池实现生产环境批量数据推送
前言 SpringBoot使用异步线程池: 1.编写线程池配置类,自定义一个线程池: 2.定义一个异步服务: 3.使用@Async注解指向定义的线程池: 这里以我工作中使用过的一个案例来做描述,我所在 ...
随机推荐
- .Net8顶级技术:边界检查之IR解析(慎入)
前言 C#这种语言之所以号称安全的,面向对象的语言.这个安全两个字可不是瞎叫的哦.因为JIT会检查任何可能超出分配范围的数值,以便使其保持在安全边界内.这里有两个概念,其一边界检查,其二IR解析.后者 ...
- There is not enough memory to perform the requested operation
今日在写bug 时 ide 突发脑溢血,崩溃了 一.修改用户目录下的 .vmoptions 找到C:\用户\用户名.WebStorm2018.1\config\webstorm64.exe.vmopt ...
- 【HarmonyOS】元服务和APP的相互跳转、相互成就
[关键字] 卡片.跳转.加桌 [背景介绍] 随着鸿蒙生态的发展,各种类型的应用都已经可以在Harmony OS上无差异的运行,面对鸿蒙新兴元服务的兴起,各大厂家可能都在考虑一个问题:如果已经有AP ...
- Kubernetes(k8s)健康性检查:livenessprobe探测和readinessprobe探测
目录 一.系统环境 二.前言 三.Kubernetes健康性检查简介 四.创建没有探测机制的pod 五.添加livenessprobe探测 5.1 使用command的方式进行livenessprob ...
- 搭建一个属于自己的springboot项目
一.确定环境 最近公司要上个新系统,指定由我来带两个人进行开发,既然是新项目,那么项目搭建的事就落到我的头上了.现在都是使用springboot进行开发,为此我搭环境使用的是springboot,具体 ...
- 可视化生信分析利器 Galaxy 之 Docker 开发
1. 背景 我们常常会基于某个 image 来启动一个 container,在这个 container 中我们可能会执行某些操作,比如创建一个文件,但是当这个 container 退出以后,如果我们以 ...
- 【GIS】图层中多个面要素融合成一个面要素
对于那些利用GIS信息进行编辑,设计的GIS专业人士来说,桌面GIS占有主导地位.GIS专业人士使用标准桌面作为工具来设计,共享,管理和发布地理信息. ArcGIS Desktop是一 ...
- Java类加载原理中为何要设计双亲委派机制
首先,给大家演示两个示例代码,我们自定义一个与Java核心类库中java.lang.String类名相同的代码: package java.lang; /** * 自定义java.lang.Strin ...
- 前端vue uni-app列表组件 list组件,简单好用
快速实现uni-app列表组件 list组件,简单好用; 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=12675 效果图如下: ...
- Python运维开发之路《编程》
一.编程思想介绍 1.编程范式 编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程,一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现 ...