線程池(ThreadPoolExecutor)實現原理和源碼細節是Java高并發面試和實戰開發的重點


一、線程池核心流程圖

+-----------------+
|    提交任務      | submit/execute
+-----------------+|v
+-----------------+
| 判斷核心線程數  | < corePoolSize?
+-----------------+|Yes        |Nov           v
[創建新線程]   +-----------------+| 隊列是否滿?     |+-----------------+|No        |Yesv           v[入隊列排隊]   +------------------+| 判斷最大線程數  |+------------------+|No          |Yesv             v[創建新線程]   [執行拒絕策略]

二、線程池主要環節及源碼方法

1. 任務提交(execute/submit)

方法:

  • execute(Runnable command)
  • submit(Runnable/Callable)

源碼片段:

public void execute(Runnable command) {if (command == null)throw new NullPointerException();int c = ctl.get();if (workerCountOf(c) < corePoolSize) {if (addWorker(command, true))return;c = ctl.get();}if (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();if (!isRunning(recheck) && remove(command))reject(command);else if (workerCountOf(recheck) == 0)addWorker(null, false);}else if (!addWorker(command, false))reject(command);
}

注釋速記:

  • 任務先嘗試用核心線程處理。
  • 核心線程滿則嘗試入隊列。
  • 隊列滿則嘗試新建非核心線程。
  • 實在不行,執行拒絕策略。

口訣:
先核心,后隊列;隊列滿,再擴容;全滿員,拒絕它。


2. 核心線程判斷與創建

方法:

  • addWorker(Runnable firstTask, boolean core)

源碼片段:

private boolean addWorker(Runnable firstTask, boolean core) {retry:for (;;) {int c = ctl.get();int rs = runStateOf(c);// ...省略狀態判斷for (;;) {int wc = workerCountOf(c);if (wc >= CAPACITY ||wc >= (core ? corePoolSize : maximumPoolSize))return false;if (compareAndIncrementWorkerCount(c))break retry;c = ctl.get();if (runStateOf(c) != rs)continue retry;}}// ...真正創建Worker線程
}

注釋速記:

  • 根據core參數決定是否用核心線程池大小。
  • 用CAS增加線程計數,線程安全。

口訣:
核心先上,CAS搶位,線程安全,才創建。


3. 入隊列

方法:

  • workQueue.offer(command)

源碼片段:

if (isRunning(c) && workQueue.offer(command)) {// 入隊成功后可能需要喚醒線程
}

注釋速記:

  • 隊列沒滿則入隊。
  • 入隊后如果線程都在忙,線程池不會立刻擴容。

口訣:
隊列能放,直接排隊。


4. 非核心線程擴容

邏輯:

  • 當核心線程和隊列都滿時,允許創建新線程(最大線程數以內)。

源碼片段:

else if (!addWorker(command, false))reject(command);

注釋速記:

  • 只有在核心線程和隊列都滿時才會擴容到最大線程數。

口訣:
滿員排隊,再擴容。


5. 拒絕策略

方法:

  • RejectedExecutionHandler.rejectedExecution(Runnable r, ThreadPoolExecutor e)

源碼片段:

public static class AbortPolicy implements RejectedExecutionHandler {public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {throw new RejectedExecutionException();}
}

注釋速記:

  • 線程池和隊列都滿時,根據策略處理(拋異常/丟棄/調用者執行等)。

口訣:
全都滿員,策略管。


6. 線程回收與銷毀

方法:

  • worker.run()
  • 判斷空閑時間超過keepAliveTime

源碼片段:

while (task != null || (task = getTask()) != null) {// 執行任務
}

注釋速記:

  • 非核心線程空閑時間到達后會被回收。
  • 核心線程默認不會被回收(可通過allowCoreThreadTimeOut配置)。

口訣:
閑太久,自動走。


三、流程口訣速記

提任務,先核心,隊列排,擴滿員;全滿員,策略管;空閑久,自動走。


四、常用方法與內部邏輯簡表

階段關鍵方法/類主要邏輯說明
任務提交execute/submit任務進線程池
核心線程判斷addWorker(core=true)核心線程是否有空位,有則新建
入隊列workQueue.offer核心線程滿,隊列沒滿則排隊
非核心線程addWorker(core=false)隊列滿,是否可新建非核心線程
拒絕策略RejectedExecutionHandler全部滿員,執行拒絕策略
線程回收allowCoreThreadTimeOut非核心線程閑置超時自動銷毀

五、源碼脈絡圖(偽代碼)

execute(command) {if (核心線程未滿)addWorker(command, true)  // 新核心線程else if (隊列未滿)workQueue.offer(command)  // 入隊列else if (線程池未滿)addWorker(command, false) // 新非核心線程elsereject(command)           // 拒絕策略
}

六、速記口訣總結

場景口訣
任務進池先核心,后隊列
隊列滿了再擴容(到最大線程數)
全滿員策略管(拒絕策略)
線程回收閑太久,自動走
全流程提任務,先核心,隊列排,擴滿員;全滿員,策略管;空閑久,自動走。

七、配圖(流程圖)

         +-------------------------+|      提交任務           |+-------------------------+|+-------------+-------------+|                           |
+-----v-----+               +-----v-----+
| 核心線程? |----是-------->| 創建線程  |
+-----------+               +-----------+|否|
+-----v-----+
| 隊列滿?   |----否-------> 入隊列
+-----------+|是|
+-----v-----+
| 最大線程? |----否-------> 創建線程
+-----------+|是|
+-----v-----+
| 拒絕策略  |
+-----------+

八、結語

通過以上細化,線程池的工作原理、源碼關鍵點、方法流程、口訣速記都一目了然。
只要記住口訣和流程圖,結合源碼細節,面試和實戰都能輕松拿捏!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/83325.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83325.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/83325.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

學習海康VisionMaster之直方圖工具

一&#xff1a;進一步學習了 今天學習下VisionMaster中的直方圖工具&#xff1a;就是統計在ROI范圍內進行灰度級分布的統計 二&#xff1a;開始學習 1&#xff1a;什么是直方圖工具&#xff1f; 直方圖工具針對輸入灰度圖像的指定ROI區域&#xff0c;輸出該區域的圖像灰度直方…

計算機網絡 : Socket編程

計算機網絡 &#xff1a; Socket編程 目錄 計算機網絡 &#xff1a; Socket編程引言1.UDP網絡編程1.1 網絡地址與端口轉換函數1.2 本地環回1.3 EchoServer1.4 DictServer1.5 DictServer封裝版1.6 簡單聊天室 2.TCP網絡編程2.1 TCP Socket API詳解2.2 Echo Server2.3 Echo Serve…

Elasticsearch/OpenSearch 中doc_values的作用

目錄 1. 核心作用 2. 適用場景 3. 與 index 參數的對比 4. 典型配置示例 場景 1&#xff1a;僅用于聚合&#xff0c;禁止搜索 場景 2&#xff1a;優化大字段存儲 5. 性能調優建議 6. 底層原理 doc_values 是 Elasticsearch/OpenSearch 中用于優化查詢和聚合的列式存儲結…

使用mermaid 語言繪畫時序圖和鏈路圖

給大家展示一下效果&#xff0c; 官方地址&#xff1a;https://mermaid.nodejs.cn/ 官方開發地&#xff1a;https://mermaid.nodejs.cn/intro/#google_vignette graph LR%% 樣式定義&#xff08;完全保留&#xff09; classDef user fill:#E1F5FE,stroke:#0288D1;classDef …

C++ Kafka客戶端(cppkafka)安裝與問題解決指南

一、cppkafka簡介 cppkafka是一個現代C的Apache Kafka客戶端庫&#xff0c;它是對librdkafka的高級封裝&#xff0c;旨在簡化使用librdkafka的過程&#xff0c;同時保持最小的性能開銷。 #mermaid-svg-qDUFSYLBf8cKkvdw {font-family:"trebuchet ms",verdana,arial,…

STM32的ADC模塊中,**采樣時機(Sampling Time)**和**轉換時機(Conversion Time),獲取數據的時機詳解

在STM32的ADC模塊中&#xff0c;**采樣時機&#xff08;Sampling Time&#xff09;和轉換時機&#xff08;Conversion Time&#xff09;**是ADC工作流程中的兩個關鍵階段&#xff0c;直接影響采樣精度和系統實時性。以下是詳細解析&#xff1a; 1. 采樣時機&#xff08;Samplin…

Pageassist安裝(ollama+deepseek-r1)

page-assist網站&#xff1a;https://github.com/n4ze3m/page-assist 首先電腦配置node.js&#xff0c;管理員打開命令窗口輸入下面命令下載bun npm install -g buncd 到你想要安裝page-assist的地方&#xff08;推薦桌面&#xff09; 輸入下列命令 git clone https://gith…

APC 熒光通道專用!Elabscience? CD11b 抗體激發 / 發射光譜精準匹配流式檢測

內容概要 Elabscience APC Anti-Mouse/Human CD11b Antibody [M1/70]&#xff08;貨號&#xff1a;E-AB-F1081E&#xff09;是一款高特異性熒光標記抗體&#xff0c;適用于流式細胞術&#xff08;FCM&#xff09;&#xff0c;可精準檢測小鼠和人類樣本中的 CD11b 髓系細胞&…

entity線段材質設置

在cesium中,我們可以改變其entity線段材質,這里以直線為例. 首先我們先創建一條直線 const redLine viewer.entities.add({polyline: {positions: Cesium.Cartesian3.fromDegreesArray([-75,35,-125,35,]),width: 5,material:material, 保存后可看到在地圖上創建了一條線段…

大模型數據分析破局之路20250512

大模型數據分析破局之路 本文面向 AI 初學者、數據分析從業者與企業技術負責人&#xff0c;圍繞大模型如何為數據分析帶來范式轉變展開&#xff0c;從傳統數據分析困境談起&#xff0c;延伸到 LLM MCP 的協同突破&#xff0c;最終落腳在企業實踐建議。 &#x1f30d; 開篇導語…

【MySQL】索引太多會怎樣?

在 MySQL 中&#xff0c;雖然索引可以顯著提高查詢效率&#xff0c;但過多的索引&#xff08;如超過 5-6 個&#xff09;會帶來以下弊端&#xff1a; 1. 存儲空間占用增加 每個索引都需要額外的磁盤空間存儲索引樹&#xff08;BTree&#xff09;。對于大表來說&#xff0c;多個…

使用PocketFlowSharp創建一個Human_Evaluation示例

效果 實踐 有時候AI生成的結果我們并不滿意在進入下一步之前&#xff0c;我們需要對AI生成的結果進行人工審核&#xff0c;同意了才能進入下一個流程。 Human_Evaluation就是人工判斷的一個簡單示例。 internal class Program{static async Task Main(string[] args){// Load…

【項目】自主實現HTTP服務器:從Socket到CGI全流程解析

00 引言 ? 在構建高效、可擴展的網絡應用時&#xff0c;理解HTTP服務器的底層原理是一項必不可少的技能。現代瀏覽器與移動應用大量依賴HTTP協議完成前后端通信&#xff0c;而這一過程的背后&#xff0c;是由網絡套接字驅動的請求解析、響應構建、數據傳輸等一系列機制所支撐…

SQL練習(6/81)

目錄 1.尋找連續值 方法一&#xff1a;使用自連接&#xff08;Self-Join&#xff09; 方法二&#xff1a;使用窗口函數&#xff08;Window Functions&#xff09; 2.尋找有重復的值 GROUP BY子句 HAVING子句 常用聚合函數&#xff1a; 3.找不存在某屬性的值 not in no…

【流程控制結構】

流程控制結構 流程控制結構1、順序結構2、選擇結構if基本選擇結構if else語法多重if語法嵌套if語法switch選擇結構 3、循環結構循環結構while循環結構程序調試for循環跳轉語句區別 流程控制結構 1、順序結構 流程圖 優先級 2、選擇結構 if基本選擇結構 單if 語法 if&…

【機器人】復現 UniGoal 具身導航 | 通用零樣本目標導航 CVPR 2025

UniGoal的提出了一個通用的零樣本目標導航框架&#xff0c;能夠統一處理多種類型的導航任務。 支持 對象類別導航、實例圖像目標導航和文本目標導航&#xff0c;而無需針對特定任務進行訓練或微調。 本文分享UniGoal復現和模型推理的過程&#xff5e; 查找沙發&#xff0c;模…

python + flask 做一個圖床

1. 起因&#xff0c; 目的: 對這個網站&#xff1a;https://img.vdoerig.com/ &#xff0c; 我也想實現這種效果。做一個簡單的圖床&#xff0c;后面&#xff0c;可以結合到其他項目中。 2. 先看效果 實際效果。 3. 過程: Grok 聊天&#xff1a; https://img.vdoerig.co…

Java生產環境設限參數教學

哈哈&#xff0c;這個問題問得好&#xff01;咱們用開餐廳的比喻來理解生產環境的四大必須設限參數&#xff0c;保證你聽完再也不會忘&#xff01;&#xff08;搓手手&#xff09; 1. 堆內存上限&#xff1a;-Xmx&#xff08;廚房的最大容量&#xff09; 問題&#xff1a;想象…

電腦出故障驅動裝不上?試試驅動人生的遠程服務支持

在日常工作或學習中&#xff0c;驅動問題時常成為電腦用戶的一大困擾。尤其是在更換硬件、重裝系統、驅動沖突等情況下&#xff0c;許多用戶往往手足無措&#xff0c;不知道從何下手。而“驅動人生”作為國內領先的驅動管理工具&#xff0c;一直以高效、便捷、智能著稱。現在&a…

JS手寫代碼篇---手寫 instanceof 方法

2、手寫 instanceof 方法 instancecof用于檢測一個對象是否是某個構造函數的實例。它通常用于檢查對象的類型&#xff0c;尤其是在處理繼承關系時。 eg: const arr [1,2,3,4,5]console.log(arr instanceof Array); // trueconsole.log(arr instanceof Object); // true那這是…