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