最近项目中用到了该注解,对其查找线程池的顺序比较困惑,查阅资料简单整理在此。

 

注意的点

* 必须用在public方法上
* 在某异步方法的同一个类的其他方法调用此异步方法无效

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;
}