spring服务端的实际开发中,经常会遇到需要提前返回响应,然后服务器在继续处理逻辑的情况。
比如,当一个逻辑处理时需要大量资源,并且用户不需要感知结果时。
或者,当用户操作一个动作时,服务器需要连带做一些其他额外的内部逻辑,是不需要用户感知的。
这时候就需要异步调用,即在当前http线程之外单独开一个线程,完成额外的逻辑,本线程完成处理逻辑后直接返回响应。
在spring体系下,提供了一个@Async注解。
public Response regitser(User user) {
...
// 新增用户
userService.addUser(user)
...
// 通知相关人员有用户注册
notifyRegister(user)
...
}
这个场景下,用户注册后,需要通知公司相关人员,已有用户注册,这个逻辑是不需要改请求的用户感知的,且可能需要通过其他通讯方式通知到相关人员,所以资源消耗较大,且花费时间较长。
所以对于notifyRegister()方法是有必要单独开一个线程的。
@Async
public void notifyRegister(User user) {
...
}
所以在该方法上添加@Async注解,并且在configuration类或Application类增加@EnableAsync注解
以上使用的是spring提供的默认线程池
但是如果这种情况线程较多,且类型不同,希望多个线程池互相不干扰。
则可以配置不同的线程池,然后在使用@Async注解时指定线程池。
@Configuration
@EnableAsync
public class AsyncConfiguration {
@Bean("aaaExecutor")
public Executor aaaExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(Integer.MAX_VALUE);
executor.initialize();
return executor;
}
@Bean("bbbExecutor")
public Executor bbbExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(Integer.MAX_VALUE);
executor.initialize();
return executor;
}
}
@Async("bbbExecutor")
public void notifyRegister(User user) {
...
}
上面定义配置了两个不同的线程池,然后在不同场景下,指定不同的线程池。