本文產生原因
羣友問題:
使用ThreadPoolExecutor實現固定大小的線程池,但是程序跑一段時間後,就會重新創建新的線程,求問有人遇到過這個問題嗎?
詢問工作隊列,最大線程數,超時時間參數值設置
猜測
隊列太小。容易導致隊列滿後,啓動非核心線程。懷疑 keepAliveTime爲0,導致線程池的線程runWorker期間,調用getTask不等待。
線程池
new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, workQueue,Executors.defaultThreadFactory(), defaultHandler);
execute提交任務時:
當execute時,線程小於corePoolSize,則addWorker(firstTask,true)創建新線程。
當線程數量 大於核心數量corePoolSize後,則將任務入隊。
當workQueue到達最大數量時,繼續創建線程直到線程數量大於maximumPoolSize
當線程數量大於maximumPoolSize後,執行拒絕策略defaultHandler
TERMINALTED:當非core線程空閒時間(getTask)超過keepAliveTime, timeUnit指定的時間後,則退出。
threadPoolExecutor允許核心線程退出,類似於5.
線程池中的線程何時死亡?
源碼
查看源碼,【keepAliveTime爲0,會在隊列爲空的時候不等待】,返回0.(這裏是ArrayBlockingQueue的實現)
測試
jvisualVM 查看線程
現象:能看見在不斷創建線程。應該有一個核心線程,但所有線程的name都在變化。
結論:
- keepAliveTime爲0以及隊列太小導致ThreadPoolExecutor不斷創建新線程
- 核心線程並不指的最先創建的那幾個。 而是指當前少於core線程就算核心線程。
- keepAliveTime爲0導致非core線程運行完後就休眠。查看ThreadPoolExecutor#getTask