keepAliveTime爲0以及隊列太小導致ThreadPoolExecutor不斷創建新線程

本文產生原因

羣友問題:

使用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都在變化。

在這裏插入圖片描述

結論:

  1. keepAliveTime爲0以及隊列太小導致ThreadPoolExecutor不斷創建新線程
  2. 核心線程並不指的最先創建的那幾個。 而是指當前少於core線程就算核心線程。
  3. keepAliveTime爲0導致非core線程運行完後就休眠。查看ThreadPoolExecutor#getTask

線程池中的線程何時死亡?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章