2 Async

Wu Jun 2020-01-10 10:38:51
06 Spring > 07 Async

1 异步

1.1 异步调用

@EnableAsync 启用 @Async 注解

@SpringBootApplication
@EnableAsync
public class Application {}

使用 @Async 注解将同步函数变为异步函数

@Component
public class Task {
    @Async
    public void doTaskOne() throws Exception {
        //...
    }
}

1.2 异步回调

使用 Future 来返回异步调用的结果

@Async
public Future<String> doTaskOne() throws Exception {
    Thread.sleep(random.nextInt(10000));
    return new AsyncResult<>("任务完成");
}

测试

Future<String> task = task.doTaskOne();
while(true) {
	if(task.isDone()) {
		break;
	}
	Thread.sleep(1000);
}
task.get();

2 线程池

2.1 自定义线程池

使用 ThreadPoolTaskExecutor 创建线程池

@EnableAsync
@Configuration
class TaskPoolConfig {

    @Bean("taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(200);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("taskExecutor-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}

2.2 使用线程池

在 @Async 注解中指定线程池名

@Async("taskExecutor")
public void doTaskOne() throws Exception {
    Thread.sleep(random.nextInt(10000));
}

2.3 线程池资源关闭

主要针对 ThreadPoolTaskScheduler 线程池。

@Bean("taskExecutor")
public Executor taskExecutor() {
    ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler();
    executor.setPoolSize(20);
    executor.setThreadNamePrefix("taskExecutor-");
    executor.setWaitForTasksToCompleteOnShutdown(true);
    executor.setAwaitTerminationSeconds(60);
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    return executor;
}