偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

我們一起聊聊并發(fā)編程:線程池

開發(fā) 前端
首先判斷corePoolSize,其次判斷blockingQueue是否已滿,接著判斷maxPoolSize, 最后使用拒絕策略。 很顯然,基于這種流程,如果隊(duì)列是無界的,將永遠(yuǎn)沒有機(jī)會走到步驟三,也即maxPoolSize沒有 使用,也一定不會走到步驟四。

一、線程池的實(shí)現(xiàn)原理

下圖所示為線程池的實(shí)現(xiàn)原理:調(diào)用方不斷地向線程池中提交任務(wù);線程池中有一組線程,不斷地 從隊(duì)列中取任務(wù),這是一個典型的生產(chǎn)者—消費(fèi)者模型。

要實(shí)現(xiàn)這樣一個線程池,有幾個問題需要考慮:

1. 隊(duì)列設(shè)置多長?如果是無界的,調(diào)用方不斷地往隊(duì)列中放任務(wù),可能導(dǎo)致內(nèi)存耗盡。如果是有 界的,當(dāng)隊(duì)列滿了之后,調(diào)用方如何處理?

2. 線程池中的線程個數(shù)是固定的,還是動態(tài)變化的?

3. 每次提交新任務(wù),是放入隊(duì)列?還是開新線程?

4. 當(dāng)沒有任務(wù)的時候,線程是睡眠一小段時間?還是進(jìn)入阻塞?如果進(jìn)入阻塞,如何喚醒?

針對問題4,有3種做法:

1. 不使用阻塞隊(duì)列,只使用一般的線程安全的隊(duì)列,也無阻塞/喚醒機(jī)制。當(dāng)隊(duì)列為空時,線程 池中的線程只能睡眠一會兒,然后醒來去看隊(duì)列中有沒有新任務(wù)到來,如此不斷輪詢。

2. 不使用阻塞隊(duì)列,但在隊(duì)列外部、線程池內(nèi)部實(shí)現(xiàn)了阻塞/喚醒機(jī)制。

3. 使用阻塞隊(duì)列。

很顯然,做法3最完善,既避免了線程池內(nèi)部自己實(shí)現(xiàn)阻塞/喚醒機(jī)制的麻煩,也避免了做法1的睡 眠/輪詢帶來的資源消耗和延遲。正因?yàn)槿绱?,接下來要講的
ThreadPoolExector/ScheduledThreadPoolExecutor都是基于阻塞隊(duì)列來實(shí)現(xiàn)的,而不是一般的隊(duì)列, 至此,各式各樣的阻塞隊(duì)列就要派上用場了

二、線程池的類繼承體系

在這里,有兩個核心的類: ThreadPoolExector 和
ScheduledThreadPoolExecutor ,后者不僅 可以執(zhí)行某個任務(wù),還可以周期性地執(zhí)行任務(wù)。

向線程池中提交的每個任務(wù),都必須實(shí)現(xiàn) Runnable 接口,通過最上面的 Executor 接口中的 execute(Runnable command) 向線程池提交任務(wù)。

然后,在ExecutorService 中,定義了線程池的關(guān)閉接口 shutdown() ,還定義了可以有返回值 的任務(wù),也就是 Callable ,后面會詳細(xì)介紹。

三、ThreadPoolExecutor

1、核心數(shù)據(jù)結(jié)構(gòu)

基于線程池的實(shí)現(xiàn)原理,下面看一下ThreadPoolExector的核心數(shù)據(jù)結(jié)構(gòu)。

每一個線程是一個Worker對象。Worker是ThreadPoolExector的內(nèi)部類,核心數(shù)據(jù)結(jié)構(gòu)如下:

由定義會發(fā)現(xiàn),Worker繼承于AQS,也就是說Worker本身就是一把鎖。這把鎖有什么用處呢?用于線程池的關(guān)閉、線程執(zhí)行任務(wù)的過程中。

2、核心配置參數(shù)解釋

ThreadPoolExecutor在其構(gòu)造方法中提供了幾個核心配置參數(shù),來配置不同策略的線程池。

上面的各個參數(shù),解釋如下:

1. corePoolSize:在線程池中始終維護(hù)的線程個數(shù)。

2. maxPoolSize:在corePooSize已滿、隊(duì)列也滿的情況下,擴(kuò)充線程至此值。

3. keepAliveTime/TimeUnit:maxPoolSize 中的空閑線程,銷毀所需要的時間,總線程數(shù)收縮 回corePoolSize。

4. blockingQueue:線程池所用的隊(duì)列類型。

5. threadFactory:線程創(chuàng)建工廠,可以自定義,有默認(rèn)值
Executors.defaultThreadFactory()

6. RejectedExecutionHandler:corePoolSize已滿,隊(duì)列已滿,maxPoolSize 已滿,最后的拒 絕策略。

下面來看這6個配置參數(shù)在任務(wù)的提交過程中是怎么運(yùn)作的。在每次往線程池中提交任務(wù)的時候,有 如下的處理流程:

步驟一:判斷當(dāng)前線程數(shù)是否大于或等于corePoolSize。如果小于,則新建線程執(zhí)行;如果大于, 則進(jìn)入步驟二。

步驟二:判斷隊(duì)列是否已滿。如未滿,則放入;如已滿,則進(jìn)入步驟三。

步驟三:判斷當(dāng)前線程數(shù)是否大于或等于maxPoolSize。如果小于,則新建線程執(zhí)行;如果大于, 則進(jìn)入步驟四。

步驟四:根據(jù)拒絕策略,拒絕任務(wù)。

總結(jié)一下:首先判斷corePoolSize,其次判斷blockingQueue是否已滿,接著判斷maxPoolSize, 最后使用拒絕策略。 很顯然,基于這種流程,如果隊(duì)列是無界的,將永遠(yuǎn)沒有機(jī)會走到步驟三,也即maxPoolSize沒有 使用,也一定不會走到步驟四。

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2024-12-10 00:00:25

2025-02-28 08:46:24

框架微服務(wù)架構(gòu)

2023-07-04 13:36:00

同步工具類Phaser

2023-08-10 08:28:46

網(wǎng)絡(luò)編程通信

2024-06-04 07:52:04

2025-01-09 10:57:54

2023-10-31 09:04:21

CPU調(diào)度Java

2023-08-04 08:20:56

DockerfileDocker工具

2023-06-30 08:18:51

敏捷開發(fā)模式

2023-09-10 21:42:31

2022-05-24 08:21:16

數(shù)據(jù)安全API

2021-08-27 07:06:10

IOJava抽象

2024-02-20 21:34:16

循環(huán)GolangGo

2023-11-29 07:10:50

python協(xié)程異步編程

2023-03-26 23:47:32

Go內(nèi)存模型

2022-02-23 08:41:58

NATIPv4IPv6

2024-11-28 09:57:50

C#事件發(fā)布器

2021-08-12 07:49:24

mysql

2023-07-24 09:41:08

自動駕駛技術(shù)交通

2022-10-08 00:00:05

SQL機(jī)制結(jié)構(gòu)
點(diǎn)贊
收藏

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