ThreadPoolExecutor中的keepAliveTime详解
文章目錄
- 一、keepAliveTime的概念
- 二、keepAliveTime的設置方法
- 2.1. 通過構造函數設置
- 2.2. 通過setKeepAliveTime方法動態設置
- 三、線程是如何根據keepAliveTime進行銷毀的
閱讀這篇文章,你將會知道:
keepAliveTime的概念。
keepAliveTime是如何設置的。
線程是如何根據keepAliveTime進行銷毀的。
一、keepAliveTime的概念
- 1 keepAliveTime的單位是納秒,即1s=1000000000ns,1秒等于10億納秒。
- 2 keepAliveTime是線程池中空閑線程等待工作的超時時間。
- 3 當線程池中線程數量大于corePoolSize(核心線程數量)或設置了allowCoreThreadTimeOut(是否允許空閑核心線程超時)時,線程會根據- 1 keepAliveTime的值進行活性檢查,一旦超時便銷毀線程。
- 4 否則,線程會永遠等待新的工作。
二、keepAliveTime的設置方法
2.1. 通過構造函數設置
通過 keepAliveTime 、unit共同決定實際的 keepAliveTime值,最終會轉化成納秒單位。
2.2. 通過setKeepAliveTime方法動態設置
重新設置線程池的keepAliveTime屬性,如果發現將要設置的值比原來的keepAliveTime值要小(即減小keepAliveTime),則觸發interruptIdleWorkers(),中斷空閑線程。
interruptIdleWorkers()是怎么中斷線程的呢?
(1)interruptIdleWorkers先拿出所有的工作者進行遍歷,判斷工作者對應的線程是否已經中斷。
(2)如果沒有產生中斷,則判斷是否可以獲得鎖,如果能獲得鎖,則代表是空閑線程,然后中斷該線程。
(3)至于線程的中斷在什么時候會拋出中斷異常,同學們可以自己找下資料,也可以參考下別人寫的這篇文章Java并發之線程中斷
三、線程是如何根據keepAliveTime進行銷毀的
-
1.線程池中的線程通過工作者(Worker)這個類進行包裝,Worker通過 ThreadPoolExecutor.runWorker() 這個方法進行自旋,從隊列中獲得task,并完成工作。
-
2.如果拿不到task(即firstTask == null 或 getTask() == null),則會退出自旋,進入finally代碼塊。finally中會調用processWorkerExit方法,注銷當前Worker,實現worker的銷毀。對keepAliveTime的使用,就在getTask()方法中,這個在后面講解。
-
3.getTask 怎么使用 keepAliveTime
(1)首先也是一個自旋,當allowCoreThreadTimeout(運行空閑核心線程超時) 或 wc>corePoolSize(當前線程數量大于核心線程數量) 時,timed會標識為true,表示需要進行超時判斷。
(2)當wc(當前工作者數量)大于 最大線程數 或 空閑線程的空閑時間大于keepAliveTime(timed && timeout),以及wc>1或(workQueue)任務隊列為空時,會進入compareAndDecrementWorkerCount方法,對wc的值減1。
(3)當compareAndDecrementWorkerCount方法返回true時,則getTask方法會返回null,終止getTask方法的自旋。這時候回到runWorker方法,就會進入到processWorkerExit方法,進行銷毀worker。
-
4.compareAndDecrementWorkerCount中操作的是ctl屬性:
(1)ctl是中心控制器,一個AtomicInteger類型的整數,通過數字的二進制編碼的位進行分段,不同的二進制位段表示有不同的含義。
(2)在ctl中,低29為表示線程池的容量,即線程池最大容量為 536870911 = 000 11111111111111111111111111111。
總結
以上是生活随笔為你收集整理的ThreadPoolExecutor中的keepAliveTime详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在线安装docker
- 下一篇: Keepalived时主备负载均衡器都有