用法和介紹
功能描述
使用方法
代碼示例
@EnableAsync@SpringBootApplicationpublic class StartApplication { public static void main(String[] args) { SpringApplication.run(StartApplication.class, args); }}@Servicepublic class AsyncService { /** * 使用默認線程池 */ @Async public void say(){ } /** * 指定線程池名稱 */ @Async(“getAsyncExecutor”) public void eat(){ }}@Configurationpublic class MyAsyncConfiguration { //核心線程數(shù) private static final int CORE_POOL_SIZE = 5; //最大線程數(shù) private static final int MAX_POOL_SIZE = 15; //隊列大小 private static final int QUEUE_CAPACITY = 100; //線程池中的線程的名稱前綴 private static final String THREAD_NAME = “MyThread-“; @Bean public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //配置核心線程數(shù) executor.setCorePoolSize(CORE_POOL_SIZE); //配置最大線程數(shù) executor.setMaxPoolSize(MAX_POOL_SIZE); //配置隊列大小 executor.setQueueCapacity(QUEUE_CAPACITY); //配置線程池中的線程的名稱前綴 executor.setThreadNamePrefix(THREAD_NAME); //配置線程池拒絕策略,設置為CallerRunsPolicy,當線程和隊列都滿了,由發(fā)起線程的主線程自己執(zhí)行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; }}
已實現(xiàn)的TaskExecutor線程池
- SimpleAsyncTaskExecutor:不是真的線程池,這個類不重用線程,每次調(diào)用都會創(chuàng)建一個新的線程。
- SyncTaskExecutor:這個類沒有實現(xiàn)異步調(diào)用,只是一個同步操作,只適用于不需要多線程的地方。
- ConcurrentTaskExecutor:Executor的適配類,不推薦使用。如果ThreadPoolTaskExecutor不滿足要求時,才用考慮使用這個類 。
- SimpleThreadPoolTaskExecutor:是Quartz的SimpleThreadPool的類。線程池同時被quartz和非quartz使用,才需要使用此類。
- ThreadPoolTaskExecutor :最常使用,推薦。 其實質(zhì)是對java.util.concurrent.ThreadPoolExecutor的包裝。
為什么說一定要指定線程池名稱
@Async依賴線程池,當我們未指定線程池@Async會如何選擇呢?
1. 當系統(tǒng)未配置任何線程池時
SpringBoot會默認添加一個coreSize=8的 ThreadPoolTaskExecutor 無界線程池,名稱applicationTaskExecutor。
2. 當只配置了一個TaskExecutor線程池時
使用此線程池
3. 當只配置了一個線程池,但不是TaskExecutor線程池時
使用 SimpleAsyncTaskExecutor 線和池
4. 當有多個TaskExecutor線程池時
默認使用 SimpleAsyncTaskExecutor 線程池,如果指定就使用指定的線程池(即使不是TaskExecutor類型的線程池也可以)
注意:SimpleAsyncTaskExecutor 不是真的線程池,這個類不重用線程,每次調(diào)用都會創(chuàng)建一個新的線程。強烈建議開發(fā)時指定線程池的名稱,避免創(chuàng)建多個TaskExecutor實例后,使用 SimpleAsyncTaskExecutor 線和池的情況發(fā)生