自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

美團(tuán)面試官:核心線程數(shù)為0時(shí),線程池如何執(zhí)行?

開(kāi)發(fā) 前端
當(dāng)核心線程數(shù)為 0 時(shí),當(dāng)來(lái)了一個(gè)任務(wù)之后,會(huì)先將任務(wù)添加到任務(wù)隊(duì)列,同時(shí)也會(huì)判斷當(dāng)前工作的線程數(shù)是否為 0,如果為 0,則會(huì)創(chuàng)建線程來(lái)執(zhí)行線程池的任務(wù),這就是正確的線程池執(zhí)行流程,同時(shí)也是面試官想要的答案。

線程池是 Java 中用于提升程序執(zhí)行效率的主要手段,也是并發(fā)編程中的核心實(shí)現(xiàn)技術(shù),并且它也被廣泛的應(yīng)用在日常項(xiàng)目的開(kāi)發(fā)之中。那問(wèn)題來(lái)了,如果把線程池中的核心線程數(shù)設(shè)置為 0 時(shí),線程池是如何執(zhí)行的?

要回答這個(gè)問(wèn)題,我們首先要了解在正常情況下,線程池的執(zhí)行流程,也就是說(shuō)當(dāng)有一個(gè)任務(wù)來(lái)了之后,線程池是如何運(yùn)行的?

1.線程池的執(zhí)行流程

正常情況下(核心線程數(shù)不為 0 的情況下)線程池的執(zhí)行流程如下:

  1. 判斷核心線程數(shù):先判斷當(dāng)前工作線程數(shù)是否大于核心線程數(shù),如果結(jié)果為 false,則新建線程并執(zhí)行任務(wù)。
  2. 判斷任務(wù)隊(duì)列:如果大于核心線程數(shù),則判斷任務(wù)隊(duì)列是否已滿?如果結(jié)果為 false,則把任務(wù)添加到任務(wù)隊(duì)列中等待線程執(zhí)行。
  3. 判斷最大線程數(shù):如果任務(wù)隊(duì)列已滿,則判斷當(dāng)前線程數(shù)量是否超過(guò)最大線程數(shù)?如果結(jié)果為 false,則新建線程執(zhí)行此任務(wù)。
  4. 判斷是否要執(zhí)行拒絕策略:如果超過(guò)最大線程數(shù),則將執(zhí)行線程池的拒絕策略。

如下圖所示:

圖片圖片

核心線程數(shù) VS 最大線程數(shù)

核心線程數(shù)(corePoolSize)和最大線程數(shù)(maximumPoolSize)都是線程池中的兩個(gè)重要參數(shù),其中:

  1. 核心線程數(shù)定義了線程池中最小線程數(shù)量,即使這些線程處于空閑狀態(tài),也不會(huì)被銷毀。
  2. 最大線程數(shù)定義了線程池中允許的最大線程數(shù)量,最大線程數(shù)等于核心線程數(shù) + 臨時(shí)線程數(shù),最大線程數(shù)主要是提供了一種機(jī)制來(lái)應(yīng)對(duì)突發(fā)的高并發(fā)請(qǐng)求,當(dāng)有大量任務(wù)的時(shí)候,可以創(chuàng)建線程數(shù)量的上線。

PS:在線程池的使用過(guò)程中,最大線程數(shù)必須大于等于核心線程數(shù),否則程序執(zhí)行會(huì)報(bào)錯(cuò)。

2.核心線程為0的執(zhí)行流程

那么問(wèn)題來(lái)了,按照線程池的正常執(zhí)行流程來(lái)看,如果核心線程數(shù)為 0 的話,那么當(dāng)任務(wù)來(lái)了之后會(huì)判斷當(dāng)前工作的線程數(shù)不大于核心線程數(shù),那也就不會(huì)創(chuàng)建線程執(zhí)行任務(wù)了,會(huì)將任務(wù)放到隊(duì)列。

但這個(gè)結(jié)果又很滑稽,有任務(wù)來(lái)了線程池竟然不執(zhí)行,而是先放到任務(wù)隊(duì)列中,這好像有比較奇怪,這就好比你開(kāi)了一個(gè)快遞店,當(dāng)有快遞來(lái)了之后,你想的不是如何派送,而是直接把它丟到倉(cāng)庫(kù)一樣滑稽,這會(huì)讓等快遞的人很著急,所以,我們需要驗(yàn)證一下線程池的執(zhí)行是否如我們猜想的那般,驗(yàn)證代碼如下:

// 線程池核心線程數(shù)設(shè)置為 0
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                0, 10, 1, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(10));
// 給線程池添加任務(wù)
threadPoolExecutor.execute(() -> {
    System.out.println("www.javacn.site");
});

最終程序的執(zhí)行結(jié)果如下:

圖片圖片

咦,結(jié)果怎么不符合我們的預(yù)期呢?為什么任務(wù)來(lái)了之后,沒(méi)有將任務(wù)放到任務(wù)隊(duì)列而是直接執(zhí)行了呢?

雖然程序執(zhí)行結(jié)果符合正常邏輯,但又和我們了解的線程池執(zhí)行理論相違背,這是什么原因呢?

查看線程池的執(zhí)行源碼

帶著這個(gè)疑問(wèn),我們查看了線程池的執(zhí)行源碼發(fā)現(xiàn),線程池的執(zhí)行過(guò)程遠(yuǎn)比我們想想的復(fù)雜,線程池核心源碼如下:

圖片圖片

從上面源碼可以看出,當(dāng)我們將任務(wù)添加到隊(duì)列的時(shí)候,線程池會(huì)判斷工作的線程數(shù)是否為 0,也就是上面圈出來(lái)的那行代碼,如果當(dāng)前工作線程為 0 的話,會(huì)創(chuàng)建線程執(zhí)行任務(wù)。哦,原來(lái)如此,這樣,就能將理論和實(shí)踐對(duì)應(yīng)上了。

也就是說(shuō),當(dāng)核心線程數(shù)為 0 時(shí),當(dāng)來(lái)了一個(gè)任務(wù)之后,會(huì)先將任務(wù)添加到任務(wù)隊(duì)列,同時(shí)也會(huì)判斷當(dāng)前工作的線程數(shù)是否為 0,如果為 0,則會(huì)創(chuàng)建線程來(lái)執(zhí)行線程池的任務(wù),這就是正確的線程池執(zhí)行流程,同時(shí)也是面試官想要的答案。

責(zé)任編輯:武曉燕 來(lái)源: Java中文社群
相關(guān)推薦

2024-06-20 13:59:26

2024-09-12 08:35:06

2024-09-09 15:09:30

2024-04-02 09:45:27

線程池Executors開(kāi)發(fā)

2023-05-22 08:17:04

2024-03-11 18:18:58

項(xiàng)目Spring線程池

2024-09-11 22:51:19

線程通訊Object

2024-05-16 17:58:30

線程任務(wù)線程通訊線程池

2025-01-09 11:24:59

線程池美團(tuán)動(dòng)態(tài)配置中心

2021-11-29 10:55:11

線程池Java面試

2022-06-24 06:43:57

線程池線程復(fù)用

2024-10-31 09:30:05

線程池工具Java

2020-05-22 08:11:48

線程池JVM面試

2022-02-14 16:08:15

開(kāi)源項(xiàng)目線程池動(dòng)態(tài)可監(jiān)控

2021-05-08 07:53:33

面試線程池系統(tǒng)

2021-03-29 08:47:24

線程面試官線程池

2023-12-20 14:35:37

Java虛擬線程

2021-04-08 10:51:10

主線程子線程Thread

2022-03-28 08:31:29

線程池定時(shí)任務(wù)

2010-08-27 10:53:14

面試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)