SpringBoot中的執行緒池ThreadPoolTaskExecutor,@Async的使用
執行緒池
@Configuration
@EnableAsync
public class ExcutorConfig {
@Bean(name = "ThreadPoolTaskExecutor")
public ThreadPoolTaskExecutor ThreadPoolTaskExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心執行緒數量,執行緒池建立時候初始化的執行緒數
executor.setCorePoolSize(5);
//最大執行緒數,只有在緩衝佇列滿了之後才會申請超過核心執行緒數的執行緒
executor.setMaxPoolSize(15);
//緩衝佇列,用來緩衝執行任務的佇列
executor.setQueueCapacity(20);
//當超過了核心執行緒出之外的執行緒在空閒時間到達之後會被銷燬
executor.setKeepAliveSeconds(600);
//設定好了之後可以方便我們定位處理任務所在的執行緒池
executor.setThreadNamePrefix("MyThreadPool");
//用來設定執行緒池關閉的時候等待所有任務都完成再繼續銷燬其他的Bean
executor.setWaitForTasksToCompleteOnShutdown(true);
//該方法用來設定執行緒池中任務的等待時間,如果超過這個時候還沒有銷燬就強制銷燬,以確保應用最後能夠被關閉,而不是阻塞住。
executor.setAwaitTerminationSeconds(60);
//執行緒池對拒絕任務的處理策略:這裡採用了CallerRunsPolicy策略,當執行緒池沒有處理能力的時候,該策略會直接在 execute 方法的呼叫執行緒中執行被拒絕的任務;如果執行程式已關閉,則會丟棄該任務
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 初始化
// 透過spring @Bean方式注入ThreadPoolTaskExecutor例項時,可以不需要這一步。
// 由於ThreadPoolTaskExecutor繼承了ExecutorConfigurationSupport,初始化物件時會呼叫ExecutorConfigurationSupport.afterPropertiesSet()
executor.initialize();
return executor;
}
}
非同步方法,指定使用執行緒池 :ThreadPoolTaskExecutor
@Async("ThreadPoolTaskExecutor")
public void writeFile(List<String> list, CountDownLatch count){
try (BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(Paths.get("output.txt")))) {
bos.write(String.join("", list).getBytes());
log.info("{}{}", "---"+System.currentTimeMillis()+"--- ", "ThreadName: "+Thread.currentThread().getName());
} catch (IOException e) {
e.printStackTrace();
}
finally {
count.countDown();
}
}
呼叫非同步方法
public void testThreadWrite(){
ArrayList<ArrayList<String>> lists = new ArrayList<>();
for (int i = 0; i < 100; i++) {
ArrayList<String> list = new ArrayList<>();
for (int j = 0; j < 100000; j++) {
list.add("jinnanDu:"+"_"+j+"_"+i);
}
lists.add(list);
}
CountDownLatch count = new CountDownLatch(lists.size());
for(ArrayList<String> list : lists){
asyncService.writeFile(list,count);
}
//所有任務執行完成後,日誌列印結果
try {
count.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.info("all jobs finished");
}
執行結果