最近项目中用到了该注解,对其查找线程池的顺序比较困惑,查阅资料简单整理在此。
注意的点
1、 必须用在public方法上 2、 在某异步方法的同一个类的其他方法调用此异步方法无效
Spring的异步配置
要激活Spring的异步行为,可以为配置类添加@EnableAsync注解。
@EnableAsync
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@EnableAsync 检测@Async注解。
基本用法
该注解用到需要用其他线程处理任务的方法上。
不带任何返回值的用法
@Override
@Async
public void createUserWithDefaultExecutor(){
//SimpleAsyncTaskExecutor
System.out.println("Currently Executing thread name - " + Thread.currentThread().getName());
System.out.println("User created with default executor");
}
默认Spring会搜索容器中唯一的TaskExecutor类型的Bean,或名为taskExecutor的Executor类型的bean。
如果两者都找不到,一个SimpleAsyncTaskExecutor任务执行器将被用来处理该注解的任务。
带返回值的用法
@Override
@Async
public Future createAndReturnUser() {
System.out.println("Currently Executing thread name - " + Thread.currentThread().getName());
try {
User user = new User();
user.setFirstName("John");
user.setLastName("Doe");
user.setGender("Male");
Thread.sleep(5000);
return new AsyncResult(user);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
return null;
}
下面是测试方法:
@Test
public void createAndReturnUserTest() throws ExecutionException, InterruptedException {
System.out.println("Current Thread in test class " + Thread.currentThread().getName());
long startTime = System.currentTimeMillis();
Future futureUser = userService.createAndReturnUser();
futureUser.get();
assertTrue((System.currentTimeMillis() - startTime) >= 5000);
}
定义范例
Spring默认用SimpleAsyncTaskExecutor来处理@Async注解的任务。
我们还可以利用参考下面的示例来自定义方法级别的处理器。
@Bean(name = "threadPoolExecutor")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(7);
executor.setMaxPoolSize(42);
executor.setQueueCapacity(11);
executor.setThreadNamePrefix("threadPoolExecutor-");
executor.initialize();
return executor;
}