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 线程池。
- setWaitForTasksToCompleteOnShutdown(true),设置线程池关闭的时候等待所有任务都完成再继续销毁其他的 Bean
- setAwaitTerminationSeconds(60),设置线程池中任务的等待时间,超时强制销毁,避免阻塞。
@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;
}