Java 線程池總結

一、寫在前面

參考阿里開發規約,創建線程池一般用ThreadPoolExecutor

在高并發程序中,頻繁創建與銷毀線程是一種極其低效且不可控的行為。為了解決這個問題,Java 提供了線程池(ThreadPoolExecutor)這一強大的并發框架。它不僅提高了任務處理的效率,也幫助我們更好地控制系統資源,是現代高性能服務架構中的基石。

本文將從線程池的概念、設計目的、核心實現機制、任務調度流程、Worker 管理機制等方面入手


1.1 線程池是什么

線程池是一種線程復用機制,它維護了一組可以重復使用的工作線程,任務到來時無需創建新線程,而是復用已有線程執行任務,任務執行完畢后線程不會被銷毀,而是回到池中待命。

Java 中的核心實現是 java.util.concurrent.ThreadPoolExecutor


1.2 線程池解決了什么問題

問題線程池的解決方案
線程創建銷毀開銷大線程復用,避免頻繁構造/銷毀
系統資源不可控線程數量上限可設,避免 OOM
并發請求過多無法及時處理使用阻塞隊列緩存任務,異步處理
調度和控制困難提供任務調度、拒絕策略、監控接口
缺乏任務管理能力可統一提交、執行、取消任務


二、線程池核心設計與實現

2.1 總體設計架構

Java 線程池主要由以下組件構成:

┌──────────────┐     submit(Runnable)
│  主線程調用  ├────────────────┐
└──────────────┘                ▼┌──────────────┐│任務提交 execute│└─────┬────────┘▼┌────────────┐    (1)創建核心線程執行任務│ WorkerSet  │ ←────────────────────────┐└────┬───────┘                          │▼                                  │┌────────────────┐                          ││ BlockingQueue  │ ←───────(2)入隊等待執行 │└──────┬─────────┘                          │▼                                    │(3)隊列滿,擴容線程池                  (4)滿了,執行拒絕策略▼                                    ▼┌────────────────┐                    ┌────────────────┐│ maximumPoolSize│                    │ rejectHandler()│└────────────────┘                    └────────────────┘


2.2 生命周期管理

線程池有五種狀態,由高位表示,低位為線程數量(workerCount),統一由 ctl 原子變量管理。

狀態描述
RUNNING接收新任務,處理隊列
SHUTDOWN拒收新任務,繼續處理隊列
STOP拒收新任務,中斷執行線程
TIDYING所有任務執行完,清理中
TERMINATED清理完成,徹底關閉

生命周期狀態在任務提交、線程退出、關閉線程池等場景中都會動態變化。


2.3 任務執行機制

2.3.1 任務調度流程(execute)

executor.execute(task) 時的完整流程:

  1. 線程池運行狀態檢查,若不是 RUNNING,直接拒絕任務。

  2. 線程數 < corePoolSize:創建新線程執行任務。

  3. 線程數 ≥ corePoolSize:嘗試將任務放入隊列。

  4. 隊列已滿 && 線程數 < maximumPoolSize:創建非核心線程執行任務。

  5. 隊列滿 && 已達最大線程數:執行拒絕策略(默認拋異常)。


2.3.2 任務緩沖機制

任務隊列用于緩存尚未執行的任務:

隊列類型特性
ArrayBlockingQueue有界 FIFO 隊列,避免內存溢出
LinkedBlockingQueue默認無界隊列,適合任務速率平穩
SynchronousQueue不存儲任務,適用于高并發
PriorityBlockingQueue支持優先級任務

任務是否入隊,決定了線程是否擴容。


2.3.3 任務申請(線程取任務)

任務的獲取由 getTask() 方法完成:

  • 優先從隊列中 poll 一個任務

  • 若獲取失敗,且超出 keepAliveTime,線程會退出

  • 如果線程池關閉,線程立即退出


2.3.4 任務拒絕策略

當線程池無法接收任務時,會調用 RejectedExecutionHandler

策略描述
AbortPolicy(默認)拋出異常
DiscardPolicy直接丟棄任務
DiscardOldestPolicy丟棄隊列中最老的任務
CallerRunsPolicy調用線程自己執行任務(削峰)

合理的拒絕策略有助于保護系統穩定性。


2.4 Worker 線程管理機制

2.4.1 Worker 線程

Worker 是線程池中用于執行任務的線程封裝類,它本質是一個實現了 Runnable 接口的任務執行單元,每個 Worker 包含:

  • 一個真正的 Thread 對象

  • 一個任務任務引用

  • 一個 run() 循環體:從隊列中不斷拉取任務執行


2.4.2 Worker 線程的創建(addWorker)

線程池根據當前任務和線程數決定是否調用 addWorker() 增加線程:

  • 當線程數 < corePoolSize:創建核心線程

  • 當隊列已滿 && 線程數 < maximumPoolSize:創建臨時線程

使用 ThreadFactory 可定制線程名稱、優先級等。


2.4.3 Worker 線程的回收

非核心線程超過 keepAliveTime 會被自動回收:

  • 降低資源占用

  • 避免長期占用 CPU/內存

  • 通過 allowCoreThreadTimeOut(true) 也可使核心線程超時回收

回收邏輯在 getTask() 中實現。


2.4.4 Worker 線程執行任務流程

Worker 啟動后,在 run() 方法中循環調用:

while ((task != null || (task = getTask()) != null)) {beforeExecute()try {task.run();} finally {afterExecute()}
}

執行完任務后嘗試從隊列中取下一個任務,直到線程超時或線程池關閉。


總結

Java 的線程池設計是非常經典的“并發容器”之一,其優雅地處理了:

  • 線程的 復用與銷毀

  • 任務的 排隊與拒絕

  • 系統的 穩定性與擴展性

它不是簡單的任務線程分發器,更是一個具備“智能調度、彈性擴容、精細管控”能力的多線程平臺。


附錄:推薦配置建議

場景核心參數建議
接口服務corePoolSize = CPU 核心數,隊列有限,拒絕策略為 CallerRuns
IO 密集maximumPoolSize 設置略高,使用 SynchronousQueue
定時任務使用 ScheduledThreadPoolExecutor
高并發網關使用自定義線程工廠 + 有界隊列 + 指標監控

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

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

相關文章

【3.3】Pod詳解——容器探針部署第一個pod

文章目錄 容器探針小知識-控制平面Pod實戰聲明式模型&命令模式 部署第一個pod編寫pod清單文件kubectl命令將清單文件post到api-server驗證pod刪除pod 容器探針 上面已經講到容器狀態,那么這些容器的狀態是怎么檢測到的呢?實際上在pod中有三種探針&#xff0c;存活探針(li…

Insar 相位展開真實的數據集的生成與下載(隨機矩陣放大,zernike 仿真包裹相位)

1.真實的數據集下載: Delta-X: UAVSAR L1B Interferometric Products, MRD, Louisiana, 2021 | NASA Earthdata 注意下載的時候需要注冊登錄一下哦 2. 適用于 深度學習訓練的數據集 通過網盤分享的文件:InSAR-DLPU.rar 鏈接: https://pan.baidu.com/s/1CRWAuNYwCHP_iqCeIhf…

C++ 多線程深度解析:掌握并行編程的藝術與實踐

在現代軟件開發中&#xff0c;多線程&#xff08;multithreading&#xff09;已不再是可選項&#xff0c;而是提升應用程序性能、響應速度和資源利用率的核心技術。隨著多核處理器的普及&#xff0c;如何讓代碼有效地利用這些硬件資源&#xff0c;成為每個 C 開發者必須掌握的技…

(線性代數)矩陣的奇異值Singular Value

矩陣的奇異值是矩陣分析中一個非常重要的概念&#xff0c;尤其是在數值線性代數、數據降維&#xff08;如PCA&#xff09;、圖像處理等領域有著廣泛應用。奇異值分解&#xff08;SVD, Singular Value Decomposition&#xff09;是一種強大的工具&#xff0c;可以將任意形狀的矩…

數據結構復習4

第四章 串 一些面試題 12. 介紹一下KMP算法。★★★ KMP算法是一種高效的字符串匹配算法&#xff0c;用于在一個文本串中查找一個模式串的出現位置。KMP算法通過利用模式串自身的信息&#xff0c;在匹配過程中避免不必要的回溯&#xff0c;從而提高匹配效率。 KMP算法的核心思…

【八股消消樂】消息隊列優化—消息有序

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一個正在變禿、變強的文藝傾年。 &#x1f514;本專欄《八股消消樂》旨在記錄個人所背的八股文&#xff0c;包括Java/Go開發、Vue開發、系統架構、大模型開發、具身智能、機器學習、深度學習、力扣算法等相關知識點&#xff…

2D寫實交互數字人如何重塑服務體驗?

在數字化浪潮席卷全球的當下&#xff0c;人機交互模式正經歷著前所未有的變革。從早期的文本命令行界面&#xff0c;到圖形用戶界面&#xff08;GUI&#xff09;的普及&#xff0c;再到如今語音交互、手勢識別等多模態交互技術的興起&#xff0c;我們與機器之間的溝通方式愈發自…

CI/CD GitHub Actions配置流程

騰訊云服務器寶塔FinalShellgithup 1.在云服務器上創建SSH秘鑰對&#xff0c;下載秘鑰到本地 2.在服務器中綁定秘鑰對&#xff08;綁定后&#xff0c;服務器不能將不允許密碼登錄&#xff09;綁定前先關機服務器&#xff0c;綁定后再開啟服務器 3.FinalShell改為公鑰登錄&am…

液態交互效果網頁開發--源自鴻蒙5以及iOS26的靈感

首先先來看看最終展示效果 當鼠標靠近“開始探索”的按鈕的時候&#xff0c;按鈕放大并有微弱光效 鼠標靠近之前會給視窗添加一層接近背景的朦朧感&#xff0c;當鼠標放在視窗上朦朧感消失 技術不復雜&#xff0c;這個網頁主要是使用了以下關鍵技術&#xff1a; HTML5 語義化標…

PYTHON從入門到實踐9-類和實例

# 【1】面向對象編程 class Student(object):# 可以幫屬性值綁定到對象上&#xff0c;self相當于JAVA的thisdef __init__(self, name, age):self.name nameself.age agedef speak(self):print(self.name, 說&#xff1a;老師好)if __name__ __main__:new_student1 Student(…

matplotlib 繪制極坐標圖

1、功能介紹&#xff1a; 使用了 matplotlib 庫來創建一個極坐標圖 2、代碼部分&#xff1a; import matplotlib.pyplot as plt import numpy as np# 設置中文字體 plt.rcParams[font.sans-serif] [SimHei] # 選擇黑體字體&#xff0c;支持中文 plt.rcParams[axes.unicode…

Dask心得與筆記【2】

文章目錄 計算參考文獻 計算 數組切片如下 import numpy as np import dask.array as dadata np.arange(1000).reshape(10, 100) a da.from_array(data, chunks(5, 20)) print(a[:,0:3])切片結果是前3列 dask.array<getitem, shape(10, 3), dtypeint64, chunksize(5, 3…

數據采集合規安全是品牌控價基石

在品牌控價與數據分析工作中&#xff0c;數據采集是不可或缺的前置環節。當前主流的數據采集方式為爬蟲采集&#xff0c;這種依托機器自動化操作的模式&#xff0c;取代了傳統人工逐一瀏覽、復制數據的繁瑣流程&#xff0c;大幅提升了效率。采集后的原始數據&#xff0c;會由系…

llm推理賦能action policy的探索

兄弟&#xff0c;你這個問題非常到位&#xff0c;咱分兩個問題詳細講透&#xff1a; &#x1f680; (1) HybridVLA怎么引入更好的推理能力賦能Diffusion Action&#xff1f; HybridVLA 目前設計的亮點&#xff1a; Diffusion Token 與 LLM 自回歸結合 但推理能力沒有被顯式結…

spring04-管理bean(創建、注入):基于注解

一、什么是注解&#xff1f; &#xff08;1&#xff09;注解的定義 注解&#xff08;Annotation&#xff09;是 Java 代碼中的一種特殊標記&#xff0c;用于在程序運行或編譯時提供元信息。 格式&#xff1a; 注解名(屬性名屬性值, 屬性名屬性值...)&#xff08;2&#xff…

docker安裝elasticsearch和kibana

elasticsearch版本和kibana版本需保持一致。這里我使用的都是8.18.2 安裝elasticsearch docker-compose.yml networks:es-net: external: true services:elasticsearch:container_name: es01deploy:resources:limits:cpus: 0memory: 0environment:- discovery.typesingle-no…

Python爬蟲實戰:研究sanitize庫相關技術

1. 引言 1.1 研究背景與意義 在當今數字化時代,互聯網已成為人們獲取信息、交流互動的重要平臺。隨著 Web 2.0 技術的發展,用戶生成內容 (UGC)、社交媒體嵌入、第三方插件等功能極大豐富了網頁的內容和交互性,但也帶來了嚴峻的安全挑戰。根據 Web 應用安全聯盟 (WAS) 的統…

c++ 學習(二、結構體)

目錄 一、結構體與const 二、結構體與class的區別 參考鏈接&#xff1a;69 結構體-結構體中const使用場景_嗶哩嗶哩_bilibili 一、結構體與const 調用函數的時候&#xff0c;希望這個結構體是可讀而不可寫的時候&#xff0c;傳指針&#xff0c;使用const修飾&#xff0c;方式…

機器學習開篇:算法分類與開發流程

種一棵樹最好的時間是十年前&#xff0c;其次是現在。 一、機器學習算法分類 機器學習&#xff08;ML&#xff0c;Meachine Learning&#xff09;是人工智能的核心領域&#xff0c;讓計算機從數據中學習規律并做出預測&#xff0c;本文簡單介紹機器學習的算法分類和開發流程。…

使用pyflink編寫demo并將任務提交到yarn集群

目錄 背景 一、pyflink安裝 二、編寫demo程序 三、提交yarn前準備 四、提交任務 五、踩坑記錄 1、提交任務時客戶端出現語法錯誤 2、提交任務時客戶端出現lzma包找不到 3、提交任務時客戶端出現“org.apache.flink.streaming.api.utils.PythonTypeUtils.getCollectionIn…