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

本文產生的原因

面試被問到了, 結果說的不清楚。

回來看了下。

結論

查看getTask , 當非core線程空閒時間超過keepAliveTime, timeUnit**指定的時間後,則退出
**

(ps:超過空閒時間退出這個我是知道的,但是當時本能的認爲不是問的這個,哭。。)

Thread

當Thread#run完畢後,就結束。

線程狀態

NEW: new Thread()後
RUNNABLE: thread.start()後
RUNNING: CPU調度到該線程的時候。一旦CPU放棄調度後或yield後,該線程成RUNNABLE
BLOCK: ,阻塞的IO操作,獲取鎖的時候加入到鎖的阻塞隊列,
WAITTING:sleep, wait後加入waitSet,join,selector的wakeup
TERMINALTED: 線程終止。

線程池中提交任務

threadPoolExecutor.execute(runnable);

threadPoolExecutor#execute(runnable)

可以看到當線程數少於核心數,core=true,表示需要新建線程。

在這裏插入圖片描述

addWorker(firstTask)

在這裏插入圖片描述

線程狀態new: newWorker(command)->getThreadFactory().newThread(this)

在這裏插入圖片描述

線程狀態runnable:worker.thread.start()

回到addWorker的過程中,注意這裏t.start()啓動了 worker中的線程。
在這裏插入圖片描述

線程狀態running:worker.thread.start()->run()->runWorker();

Worker是Runnable的實現類, 內部含有Thread
執行Worker實現的run()->runWorker(this)方法。
當執行完**runWorker(this)**方法,線程也就自動走向了死亡。
在這裏插入圖片描述

runWorker(this)

addWorker()#start()->runwWorker(this)

可見,線程在循環中 一直從workQueue中取出threadPoolExecutor.execute(runnable)runnable
task不爲空,就task.run執行任務。
當task爲null則退出循環。然後結束該線程
在這裏插入圖片描述

getTask()

線程啓動期間 runWorker() ,循環getTask後run。
當getTask爲空,則退出循環,結束線程。
因此,什麼時候返回null是關鍵。
下圖可見,當線程池關閉(這裏暫不細究),或者 獲取任務超時都會導致返回null.
在這裏插入圖片描述

其他介紹

ctl

一個AtomicInteger,低28位用來表示線程數,高4位用來表示線程池狀態。

The main pool control state, ctl, is an atomic integer packing
two conceptual fields
workerCount, indicating the effective number of threads
runState, indicating whether running, shutting down etc
在這裏插入圖片描述

線程池

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, workQueue,Executors.defaultThreadFactory(), defaultHandler);

execute提交任務時:

  1. 當execute時,線程小於corePoolSize,則addWorker(firstTask,true)創建新線程。
  2. 當線程數量 大於核心數量corePoolSize後,則將任務入隊。
  3. workQueue到達最大數量時,繼續創建線程直到線程數量大於maximumPoolSize
  4. 當線程數量大於maximumPoolSize後,執行拒絕策略defaultHandler
  5. TERMINALTED:當非core線程空閒時間(getTask)超過keepAliveTime, timeUnit指定的時間後,則退出。
  6. threadPoolExecutor允許核心線程退出,類似於5.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章