面試官:線程池核心線程設置為0時任務執(zhí)行流程怎么樣的
在面試時,有的面試官就喜歡這種刁鉆角度的面試問題,如果你對線程池的任務執(zhí)行流程熟悉的話,那么該題就不會難住你。所以在開始之前,我們先看下線程池相關的知識。
本文使用 JDK8 演示。
一、概念
線程池是Java中管理和重用線程的一種方式,也是實現(xiàn)并發(fā)編程的一種手段。通過使用線程池可以顯著提升多線程應用程序的性能。
線程池相對于線程來說,線程池主要解決了兩個問題,一個是線程的創(chuàng)建和銷毀代價大,另一個就是多線程并發(fā)執(zhí)行時可能導致系統(tǒng)資源不足的問題。
通過線程池,可以提前創(chuàng)建好一組一定數(shù)量的線程,并管理好這些線程的生命周期,也就是線程池中線程的存活時間,通過這些我們就可以在有需要的時候重用這些線程,減少創(chuàng)建和銷毀線程的開銷,提升系統(tǒng)的響應速度和系統(tǒng)資源利用率。
二、線程池工作流程
線程池的任務執(zhí)行流程是怎么樣的呢?
- 首先會判斷當前工作線程數(shù)量是否大于核心線程數(shù)量(corePoolSize),如果小于核心線程數(shù)量,直接創(chuàng)建線程執(zhí)行任務。如果大于核心線程數(shù)量,就將任務放入任務隊列中進行緩存。
- 判斷任務隊列容量是否已滿,如果不滿,任務放入任務隊列。
- 如果任務隊列滿了,判斷當前工作線程數(shù)量是否大于最大線程數(shù)量(maximumPoolSize),如果小于最大線程數(shù)量,創(chuàng)建線程執(zhí)行任務。
- 當工作線程已經(jīng)大于最大線程了,此時,任務會觸發(fā)拒絕策略,默認的拒絕策略是拋出異常。
任務工作流程如下圖所示:
到了這你心中有結果了嗎,是不是線程池會把該任務丟入任務隊列呢,不著急,慢慢來,下面我們一起看下源碼中是如何判斷的。
三、源碼分析
1.寫個測試方法
在實際的工作中要注意設置線程名稱以及拒絕策略哦!
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(0,10,1000,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1000), new NamedThreadFactory("zuiyu",false));
threadPoolExecutor.execute(()->{
System.out.println("醉魚Java");
});
}
2.Debug 一下
首先我們看一下execute方法就知道是如何了。
通過 debug 發(fā)現(xiàn),當代碼運行到圖中圈起來的代碼這一行時,也就是當工作線程數(shù)量為0時,會執(zhí)行下一步的創(chuàng)建線程執(zhí)行任務。
最后程序輸出了《醉魚Java》,所以當核心線程設置為 0 的時候,線程池會判斷當前工作線程為0 時,會創(chuàng)建線程執(zhí)行任務。
結論
通過簡單的 debug 了一下任務的執(zhí)行流程,核心線程設置為 0 時,當把任務丟入線程池,還是會把任務丟入任務隊列,但是也會在下一步進行判斷當前工作線程的線程數(shù)量是否為 0,如果為 0,也會創(chuàng)建線程進行執(zhí)行任務。所以現(xiàn)在你懂了嗎?