1. 简介
使用Spring Boot异步调用可以提高应用的并发能力和响应速度
2. @Async注解
@Async是Spring框架提供的一种异步调用方式。通常我们在调用一个方法时,会等待该方法执行完毕并返回结果,然后才能继续执行下一步操作。而使用@Async注解可以将该方法的执行交给另一个线程来处理,从而不会阻塞当前线程,提高程序的性能和效率。
@Async注解有以下几个属性:
- value:指定使用哪个线程池执行。
- timeout:指定异步方法执行的超时时间,单位为毫秒。
- executor:指定使用的线程池的名称。
- 异常处理:当异步任务发生异常时的处理方式。
2.1 使用
使用@Async注解:在方法上标注@Async注解,Spring会将该方法放入线程池中异步执行。
异步方法必须返回void、Future或者CompletableFuture类型的结果。如果返回void,则不能获取异步结果;如果返回Future,可以通过Future.get()方法获取异步结果;如果返回CompletableFuture,则可以使用CompletableFuture的异步回调方法获取异步结果。
@Service
public class MyService {
@Async
public CompletableFuture<String> doSomething() {
// 做一些耗时的操作
return CompletableFuture.completedFuture("done");
}
}
2.2 注意事项
在使用@Async注解时,需要注意以下几点:
-
@Async注解只能标注在public方法上。
-
@Async注解标注的方法,实际上是在调用时会生成一个代理对象来执行异步任务的。
-
@Async注解需要在@Configuration注解的类中定义一个ThreadPoolTaskExecutor或者TaskExecutor的Bean,用于线程池的配置。例如:
@Configuration
@EnableAsync
public class AppConfig implements AsyncConfigurer {
@Override
@Bean(name = "myExecutor")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(100);
executor.setQueueCapacity(10);
executor.initialize();
return executor;
}
}
-
@Async方法的返回值类型可以是Future或者CompletableFuture类型,用于获取异步调用的结果。
-
在一个类内部调用@Async方法时,会产生类内部调用,因为代理对象并不会拦截实例内部的函数调用,只会拦截通过代理对象调用的函数。所以如果在同一个类内部调用@Async方法,实际上是同步执行的。
总之,使用@Async注解需要明确异步任务和同步任务的区别,注意线程池的配置和返回值类型的选择,避免出现不必要的性能问题。
3. CompletableFuture
使用CompletableFuture:可以通过CompletableFuture的supplyAsync方法异步执行任务,并在任务完成时获取结果。
CompletableFuture.supplyAsync(() -> {
// 做一些耗时的操作
return "done";
}).thenAccept(result -> {
// 处理结果
});
4. @Scheduled
使用@Scheduled注解:可以使用@Scheduled注解定时执行任务,在任务执行过程中可以使用@Async注解进行异步处理。
@Service
public class MyService {
@Scheduled(fixedRate = 1000)
@Async
public CompletableFuture<String> doSomething() {
// 做一些耗时的操作
return CompletableFuture.completedFuture("done");
}
}
使用Spring Boot异步调用可以提高应用的并发能力和响应速度,但需要注意不要滥用异步调用,否则会对应用的性能造成负面影响。