使用@Async注解来创建异步任务的话,我可以用这种方法来实现一些并发操作,以加速任务的执行效率。但是,如果只是那样直接简单的创建来使用,可能还是会碰到一些问题。
存在什么问题呢?先来思考下,下面的这个接口,通过异步任务加速执行的实现,是否存在问题或风险呢?
@RestControllerpublic class HelloController
{
@Autowired
private AsyncTasks asyncTasks;
@GetMapping("/hello")
public String hello()
{
// 将可以并行的处理逻辑,拆分成三个异步任务同时执行 CompletableFuture<String> task1 = asyncTasks.doTaskOne(); CompletableFuture<String> task2 = asyncTasks.doTaskTwo(); CompletableFuture<String> task3 = asyncTasks.doTaskThree(); CompletableFuture.allOf(task1, task2, task3).join();
return "Hello World";
}
}
虽然,从单次接口调用来说,是没有问题的。但当接口被客户端频繁调用的时候,异步任务的数量就会大量增长:3 x n(n为请求数量),如果任务处理不够快,就很可能会出现内存溢出的情况。那么为什么会内存溢出呢?根本原因是由于Spring Boot默认用于异步任务的线程池