1. 程式人生 > >執行緒池ThreadPoolExecutor剖析

執行緒池ThreadPoolExecutor剖析

Executor框架

Java執行緒池的實現主要是通過具體類ThreadPoolExecutor來實現的。

這裡寫圖片描述
Executor:宣告execute(Runnable command)方法。(註釋:在未來某個時間執行給定的命令。該命令可能在新的執行緒、已入池的執行緒或者正呼叫的執行緒執行,這由Executor實現決定

ExecutorService:繼承Executor介面,另外新增一些其他方法,如:關閉池、返回任務處理結果。
這裡寫圖片描述

AbstractExecutorService:實現ExecutorService介面,對其宣告的方法進行具體實現。即ExecutorService的預設實現。

ThreadPoolExecutor:執行緒池具體實現類。

ThreadPoolExecutor剖析

構造

這裡寫圖片描述
引數:
corePoolSize - 池中所儲存的執行緒數,包括空閒執行緒。
maximumPoolSize - 池中允許的最大執行緒數。
keepAliveTime - 當執行緒數大於核心時,此為終止前多餘的空閒執行緒等待新任務的最長時間。
unit - keepAliveTime 引數的時間單位。
workQueue - 執行前用於保持任務的佇列。此佇列僅保持由 execute 方法提交的 Runnable 任務。
threadFactory - 執行程式建立新執行緒時使用的工廠。
handler - 由於超出執行緒範圍和佇列容量而使執行被阻塞時所使用的處理程式。

應用

當執行緒池進行初始化,構造引數workQueue(任務佇列)無論是否存在任務,執行緒池都不會立刻建立工作執行緒進行處理。(當呼叫execute、prestartCoreThread、prestartAllCoreThreads、setCorePoolSize等方法會建立工作執行緒)

execute

JDK1.7.0_79原始碼:

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();

        int
c = ctl.get(); if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } else if (!addWorker(command, false)) reject(command); }
  1. 如果少於corePoolSize的執行緒數正在執行,嘗試啟動一個新的執行緒,並且將當前command作為該執行緒的第一個任務。呼叫addWorker來原子地檢查runstate和workerCount,並且通過返回false,來防止錯誤的指示,新增不應該新增的執行緒。
  2. 如果一個task可以成功排隊,那麼我們仍然需要兩次檢查。one:我們是否需要新增一個執行緒(因為存在上次檢查的一個已經死亡)。two:執行緒池從進入此方法是否關閉。所以我們重新檢查狀態,並且如果有必要,執行緒池關閉了,可以回滾入隊,或者一個worker都沒有,那麼啟動一個新worker。
  3. 如果我們無法排隊任務,那麼我們嘗試新增一個新的執行緒。如果失敗,我們知道執行緒池關閉了或者佇列飽和了,所以拒絕這個task。

    ctl是AtomicInteger變數,儲存了兩個內容,所有執行緒的數量,每個執行緒所處狀態

測試

幫助連結