通俗易懂,各常用執行緒池執行的-流程圖

林冠巨集_指尖下的幽靈發表於2017-12-07

作者:林冠巨集 / 指尖下的幽靈

掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8

部落格:http://www.cnblogs.com/linguanh/

GitHub : https://github.com/af913337456/

有時候花了大把時間去看一些東西卻看不懂,是很 “ 藍瘦 ” 的,花時間也是投資。

本文適合:

  • 曾瞭解過執行緒池卻一直模模糊糊的人
  • 瞭解得差不多卻對某些點依然疑惑的

不適合:

  • 完全沒看過的,建議你先去看看其他基礎文章
  • 看過,卻忘得差不多了,建議你先去回顧下

本文能給你的閱讀回報

  • 適合的讀者,儘可能讓你徹底明白常用的執行緒池的知識相關點
  • 不適合的讀者,能有個不錯的概念,神童另談

廢話少說,我們開始。下圖,皆可自行儲存,常常閱之。日久,根深蒂固

預設建構函式

public ThreadPoolExecutor(
    int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    ThreadFactory threadFactory,
    RejectedExecutionHandler handler
) 
{
    ....
}
複製程式碼

絕對易懂的構造方法引數講解

引數名 作用
corePoolSize 佇列沒滿時,執行緒最大併發數
maximumPoolSizes 佇列滿後執行緒能夠達到的最大併發數
keepAliveTime 空閒執行緒過多久被回收的時間限制
unit keepAliveTime 的時間單位
workQueue 阻塞的佇列型別
RejectedExecutionHandler 超出 maximumPoolSizes + workQueue 時,任務會交給RejectedExecutionHandler來處理

文字描述

corePoolSize,maximumPoolSize,workQueue之間關係。

  • 當執行緒池中執行緒數小於corePoolSize時,新提交任務將建立一個新執行緒執行任務,即使此時執行緒池中存在空閒執行緒。

  • 當執行緒池中執行緒數達到corePoolSize時,新提交任務將被放入workQueue中,等待執行緒池中任務排程執行 。

  • 當workQueue已滿,且maximumPoolSize > corePoolSize時,新提交任務會建立新執行緒執行任務。

  • 當workQueue已滿,且提交任務數超過maximumPoolSize,任務由RejectedExecutionHandler處理。

  • 當執行緒池中執行緒數超過corePoolSize,且超過這部分的空閒時間達到keepAliveTime時,回收這些執行緒。

  • 當設定allowCoreThreadTimeOut(true)時,執行緒池中corePoolSize範圍內的執行緒空閒時間達到keepAliveTime也將回收。

一般流程圖

通俗易懂,各常用執行緒池執行的-流程圖

newFixedThreadPool 流程圖

public static ExecutorService newFixedThreadPool(int nThreads){
    return new ThreadPoolExecutor(
            nThreads,   // corePoolSize
            nThreads,   // maximumPoolSize == corePoolSize
            0L,         // 空閒時間限制是 0
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>() // 無界阻塞佇列
        );
}
複製程式碼

通俗易懂,各常用執行緒池執行的-流程圖

newCacheThreadPool 流程圖

public static ExecutorService newCachedThreadPool(){
    return new ThreadPoolExecutor(
        0,                  // corePoolSoze == 0
        Integer.MAX_VALUE,  // maximumPoolSize 非常大
        60L,                // 空閒判定是60 秒
        TimeUnit.SECONDS,
        // 神奇的無儲存空間阻塞佇列,每個 put 必須要等待一個 take
        new SynchronousQueue<Runnable>()  
    );
}

複製程式碼

通俗易懂,各常用執行緒池執行的-流程圖

newSingleThreadPool 流程圖

public static ExecutorService newSingleThreadExecutor() {
        return 
            new FinalizableDelegatedExecutorService
                (
                    new ThreadPoolExecutor
                        (
                            1,
                            1,
                            0L,
                            TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<Runnable>(),
                            threadFactory
                        )
                );
    }
複製程式碼

可以看到除了多了個 FinalizableDelegatedExecutorService 代理,其初始化和 newFiexdThreadPool 的 nThreads = 1 的時候是一樣的。 區別就在於:

  • newSingleThreadExecutor返回的ExcutorService在解構函式finalize()處會呼叫shutdown()
  • 如果我們沒有對它呼叫shutdown(),那麼可以確保它在被回收時呼叫shutdown()來終止執行緒。

使用ThreadFactory,可以改變執行緒的名稱、執行緒組、優先順序、守護程式狀態,一般採用預設。

流程圖略,請參考 newFiexdThreadPool,這裡不再累贅。

最後

還有一個定時任務執行緒池ScheduledThreadPool

它用來處理延時或定時任務,不常用

相關文章