@Async用於異步調用,用線程池裏的一個線程去處理,主線程無須等待,直接執行以後的語句官方文檔java
例如:支付(步驟A)->開鎖(步驟B)->支付信息入庫(步驟C)->...,例如開鎖步驟和主程序其餘步驟關聯不強(支付完成即使是不開鎖,用戶仍然能夠經過界面啓動)且耗時(物聯網設備通訊問題,等待返回須要時間以及失敗重試等),就能夠考慮用異步調用去處理spring
package com.virgo.user.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author zhaozha
* @date 2019/10/18 下午2:09
*/
@Configuration
public class TaskConfiguration {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心線程數
executor.setCorePoolSize(2);
// 最大線程數
// 空閒線程數=最大線程數-核心線程數
executor.setMaxPoolSize(4);
// 隊列最大容量
executor.setQueueCapacity(2);
// 空閒線程數最大存活時間
executor.setKeepAliveSeconds(60);
// 線程池名的前綴
executor.setThreadNamePrefix("taskExecutor-");
// 拒絕策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
複製代碼
@EnableAsync
複製代碼
// 本次測試在Service層加註解
@Override
public void pay() throws Exception {
Thread.sleep(new Random().nextInt(1000));
log.info("支付完成");
}
@Override
@Async("taskExecutor")
public Future<String> unlock() throws Exception {
Thread.sleep(new Random().nextInt(1000));
log.info("開鎖完成");
return new AsyncResult<>("開鎖完成");
}
@Override
public void record() throws Exception {
Thread.sleep(new Random().nextInt(1000));
log.info("記錄完成");
}
}
// Controller層調用
...
try {
commonServiceImpl.pay();
commonServiceImpl.unlock();
commonServiceImpl.record();
} catch (Exception e) {
e.printStackTrace();
}
...
複製代碼
拒絕策略(todo)bash
優雅停機dom
// 聲明線程池的時候配置
//1.線程池關閉的時候先等待任務的完成在銷燬bean
setWaitForTasksToCompleteOnShutdown(true)
//2.線程池關閉的時候先等待任務的最大時間,超過就強制銷燬
setAwaitTerminationSeconds(60)
複製代碼