SpringBoot任务——异步任务
文章目录
1.异步任务相关简介与注解
使用异步任务无非是想在做某些耗时操作的时候,不让他阻塞线程。
在springboot中可使用以下两个注解使用异步任务:
- @EnableAsync:标注于类上,表示开启Spring异步
- @Async:标注在方法上,spring便会在线程池(默认为springboot创建的,也可以自定义)的空闲线程执行该方法。
自定义线程池可通过实现AsyncConfigurer接口并重载getAsyncExecute方法实现,这里不详细说明。
2.异步任务使用场景
并不是所有耗时操作都使用异步效果会更好,不适合用的使用异步反而带来更多问题,需要满足以下条件的耗时操作:
异步使用原则:这一段文字摘自:[异步概念及使用场景]( https://www.cnblogs.com/thePeaceOftheLord/p/11644521.html )
- 不涉及共享资源,或对共享资源只读,即非互斥操作
- 没有时序上的严格关系
- 不需要原子操作,或可以通过其他方式控制原子性
- 常用于IO操作等耗时操作,因为比较影响客户体验和使用性能
- 不影响主线程逻辑
满足上述几点,使用异步会使系统效率更高。具体可异步功能举例为:发邮件/发推送/发订阅信息/生成报表等
3.异步任务举例
3.1 定义同步/异步服务 @Async注解标注为异步方法
@Service
public class AsyncService {
//没有异步处理,需要耗时操作之后才能(同步执行)
public void testSync(){
try {
System.out.println("耗时操作中...");
Thread.sleep(10000);//模拟耗时操作 10秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//含有异步处理, 使用@Async注解标注为异步方法,通知Spring开启线程池
@Async
public void testAsync() {
try {
System.out.println("耗时操作中...");
Thread.sleep(10000);模拟耗时操作 10秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3.2 控制层调用同步/异步服务
@RestController
public class TestController {
//注入业务对象
@Resource
AsyncService asyncService;
//测试同步
@GetMapping("/testSync")
public String testSync(){
asyncService.testSync();
return "Sync success!同步执行";//耗时操作阻塞线程,10秒后返回结果
}
//测试异步
@GetMapping("/testAsync")
public String testAsync(){
asyncService.testAsync();
return "Async success!异步执行";//耗时操作异步执行,没有阻塞线程,立即返回结果
}
}
3.3 启动类使用注解@EnableAsync标注:开启Spring异步
@EnableAsync//开启Spring异步
@SpringBootApplication
public class SpringbootTaskApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootTaskApplication.class, args);
}
}
3.4 测试结果
测试同步:需要10s后返回响应,即等耗时操作完全结束后返回响应。
测试异步:立即返回响应,即等耗时操作在另一个线程中执行。