Like Share Discussion Bookmark Smile

J.J. Huang   2019-04-22   Spring Boot   瀏覽次數:

SpringBoot - 第三十四章 | @Async 實現異步調用:自定義線程池

我們在前面 SpringBoot - 第三十三章 | @Async 實現異步調用 ,介紹過如何使用@Async註解來實現異步調用了。但是,對於這些異步執行的控制是我們保障自身應用健康的基本技能。本文我們就來學習一下,如果通過自定義線程池的方式來控制異步調用的並發。

這邊繼續沿用 chapter33 的專案來做範例。


定義線程池

上面我們通過使用ThreadPoolTask​​Executor建立了一個線程池,同時設置了以下這些參數:

參數 說明
核心線程數10 線程池建立時候初始化的線程數
最大線程數20 線程池最大的線程數,只有在緩衝隊列滿了之後才會申請超過核心線程數的線程
緩衝隊列200 用來緩衝執行任務的隊列
允許線程的空閒時間60秒 當超過了核心線程出之外的線程在空閒時間到達之後會被銷毀
線程池名的前綴 設置好了之後可以方便我們定位處理任務所在的線程池
線程池對拒絕任務的處理策略 這裡採用了CallerRunsPolicy策略,當線程池沒有處理能力的時候,該策略會直接在execute 方法的調用線程中運行被拒絕的任務;如果執行程序已關閉,則會丟棄該任務

使用線程池

定義了線程池之後,我們只需要在@Async註解中指定線程池名即可異步調用的執行任務使用這個線程池。

修改 AsyncTask

修改 CompleteAsyncTask

測試結果

1
2
3
4
5
6
7
8
9
10
11
2019-04-23 09:14:23.224  INFO 1186 --- [ taskExecutor-1] c.j.l.s.c.task.CompleteAsyncTask         : 開始做異步任務一
2019-04-23 09:14:23.224 INFO 1186 --- [ taskExecutor-3] c.j.l.s.c.task.CompleteAsyncTask : 開始做異步任務三
2019-04-23 09:14:23.224 INFO 1186 --- [ taskExecutor-2] c.j.l.s.c.task.CompleteAsyncTask : 開始做異步任務二
2019-04-23 09:14:24.159 INFO 1186 --- [ taskExecutor-3] c.j.l.s.c.task.CompleteAsyncTask : 完成異步任務三,耗時:934毫秒
2019-04-23 09:14:26.539 INFO 1186 --- [ taskExecutor-1] c.j.l.s.c.task.CompleteAsyncTask : 完成異步任務一,耗時:3314毫秒
2019-04-23 09:14:30.911 INFO 1186 --- [ taskExecutor-2] c.j.l.s.c.task.CompleteAsyncTask : 完成異步任務二,耗時:7686毫秒
總共耗時: 7709
任務一完成
任務二完成
任務三完成
2019-04-23 09:14:30.918 INFO 1186 --- [ Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'taskExecutor'

可以在控制台中看到所有輸出的線程名前都是之前我們定義的線程池前綴名開始的,說明使用線程池來執行異步任務成功。

註:以上參考了
程序猿DDSpring Boot中使用@Async实现异步调用:自定义线程池 文章。