作者:林冠宏
juejin.im/post/5a28b37c6fb9a044fc44a103
有時候花了大把時間去看一些東西卻看不懂,是很 “ 藍瘦 ” 的,花時間也是投資。
本文適合:
-
曾了解過線程池卻一直模模糊糊的人
-
了解得差不多卻對某些點依然疑惑的
不適合:
-
完全沒看過的,建議你先去看看其他基礎文章
-
看過,卻忘得差不多了,建議你先去回顧下
本文能給你的閱讀回報
-
適合的讀者,盡可能讓你徹底明白常用的線程池的知識相關點
-
不適合的讀者,能有個不錯的概念,神童另談
廢話少說,我們開始。下圖,皆可自行保存,常常閱之。日久,根深蒂固
默認構造函數
public ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler
)
{
....
}
絕對易懂的構造方法參數講解

文字描述
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
它用來處理延時或定時任務,不常用
推薦閱讀(點擊即可跳轉閱讀)
2. 面試題內容聚合
3. 設計模式內容聚合
4. Mybatis內容聚合
5. 多線程內容聚合
