1. 程式人生 > >【進階之路】執行緒池拓展與CompletionService操作非同步任務

【進階之路】執行緒池拓展與CompletionService操作非同步任務

> 大家好,我是練習java兩年半時間的南橘,小夥伴可以一起互相交流經驗哦。 ## 一、擴充套件ThreadPoolExecutor ### 1、擴充套件方法介紹 ![](https://img-blog.csdnimg.cn/img_convert/b805ebf5547556a68e75a50a655a0f91.png) ThreadPoolExecutor是可以擴充套件的,它內部提供了幾個可以在子類中改寫的方法(紅框內)。JDK內的註解上說,這些方法可以用以新增日誌,計時、監視或進行統計資訊的收集。是不是感覺很熟悉?有沒有一種**spring aop**中 @Around @Before @After三個註解的既視感? 我們來對比一下 | ThreadPoolExecutor| spring aop | |------|------------| | beforeExecute()(**執行緒執行之前呼叫**) | @Before(**在所攔截的方法執行之前執行** ) | | afterExecute() (**執行緒執行之後呼叫**) |@After (**在所攔截的方法執行之後執行**) | | terminated() (**執行緒池退出時候呼叫**) | | | | @Around(**可以同時在所攔截的方法前後執行**) | 其實他們的效果是一樣的,只是一個線上程池裡,一個在攔截器中。 對於ThreadPoolExecutor中的這些方法,有這樣的一些特點: - 1、**無論任務時從run中正常返回,還是丟擲一個異常而返回,afterExecute都會被呼叫**(但是如果任務在完成後帶有一個Error,那麼就不會呼叫afterExecute) - 2、同時,**如果beforeExecute丟擲一個RuntimeExecption,那麼任務將不會被執行,連帶afterExecute也不會被呼叫了**。 - 3、**線上程池完成關閉操作時會呼叫terminated,類似於try-catch中的finally操作一樣。terminated可以用來釋放Executor在其生命週期裡分配的各種資源,此外也可以用來執行傳送通知、記錄日誌亦或是收集finalize統計資訊等操作**。 ### 2、擴充套件方法實現 我們先構建一個自定義的執行緒池,它通過擴充套件方法來新增日誌記錄和統計資訊的收集。為了測量任務的執行時間,beforeExecute必須記錄開始時間並把它儲存到一個afterExecute可以訪問的地方,於是用ThreadLocal來儲存變數,用afterExecute來讀取,並通過terminated來輸出平均任務和日誌訊息。 ``` public class WeedThreadPool extends ThreadPoolExecutor { private final Thr