Java多線程實現之線程池詳解

Java多線程實現之線程池詳解

    • 一、線程池的基本概念
      • 1.1 為什么需要線程池
      • 1.2 線程池的核心思想
    • 二、Java線程池的實現
      • 2.1 Executor框架
      • 2.2 ThreadPoolExecutor構造參數
    • 三、常見線程池類型
      • 3.1 FixedThreadPool
      • 3.2 CachedThreadPool
      • 3.3 SingleThreadExecutor
      • 3.4 ScheduledThreadPool
    • 四、線程池的工作流程
    • 五、線程池的使用示例
      • 5.1 提交Runnable任務
      • 5.2 提交Callable任務
      • 5.3 定時任務
    • 六、線程池的拒絕策略
      • 6.1 AbortPolicy(默認)
      • 6.2 CallerRunsPolicy
      • 6.3 DiscardPolicy
      • 6.4 DiscardOldestPolicy
    • 七、線程池的監控與調優
      • 7.1 監控線程池狀態
      • 7.2 合理配置線程池大小
    • 八、線程池的最佳實踐
      • 8.1 避免使用Executors工廠方法
      • 8.2 正確關閉線程池
      • 8.3 使用自定義線程工廠

線程池在Java中是一種重要工具,用于管理和復用線程資源,合理使用線程池可以提高程序性能、減少資源消耗,并簡化線程管理。本文我將詳細介紹Java線程池的實現原理、常見類型以及使用方法等等,幫你更好地理解和深入Java的多線程實現。

一、線程池的基本概念

1.1 為什么需要線程池

  • 線程創建和銷毀開銷大:頻繁創建和銷毀線程會消耗大量系統資源
  • 資源管理困難:無限制創建線程可能導致系統資源耗盡
  • 控制并發度:線程池可以限制同時運行的線程數量,避免過度并發

1.2 線程池的核心思想

線程池預先創建一定數量的線程,當有任務提交時,從線程池中獲取線程執行任務,任務執行完畢后線程不會銷毀,而是返回線程池等待下一個任務。

二、Java線程池的實現

2.1 Executor框架

Java通過Executor框架提供線程池的實現,核心接口和類如下:

  • Executor:線程池的基礎接口,定義了執行任務的方法
  • ExecutorService:擴展了Executor,提供了管理線程池的方法
  • ThreadPoolExecutor:線程池的核心實現類
  • ScheduledExecutorService:支持定時任務的線程池接口
  • Executors:工具類,提供創建線程池的靜態工廠方法

2.2 ThreadPoolExecutor構造參數

public ThreadPoolExecutor(int corePoolSize,                   // 核心線程數int maximumPoolSize,                // 最大線程數long keepAliveTime,                 // 空閑線程存活時間TimeUnit unit,                      // 時間單位BlockingQueue<Runnable> workQueue,  // 任務隊列ThreadFactory threadFactory,        // 線程工廠RejectedExecutionHandler handler    // 拒絕策略
)

三、常見線程池類型

3.1 FixedThreadPool

固定大小的線程池,核心線程數和最大線程數相等:

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);

3.2 CachedThreadPool

可緩存的線程池,線程數根據需要動態調整:

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

3.3 SingleThreadExecutor

單線程執行器,確保所有任務按順序執行:

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

3.4 ScheduledThreadPool

支持定時任務的線程池:

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);

四、線程池的工作流程

  1. 提交任務:調用execute()submit()方法提交任務
  2. 線程池判斷
    • 如果當前線程數小于核心線程數,創建新線程執行任務
    • 如果當前線程數大于等于核心線程數,將任務放入任務隊列
    • 如果任務隊列已滿且線程數小于最大線程數,創建新線程執行任務
    • 如果任務隊列已滿且線程數大于等于最大線程數,執行拒絕策略
  3. 任務執行完畢:線程返回線程池,等待下一個任務

五、線程池的使用示例

5.1 提交Runnable任務

ExecutorService executor = Executors.newFixedThreadPool(5);for (int i = 0; i < 10; i++) {final int taskId = i;executor.execute(() -> {System.out.println("執行任務: " + taskId);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("任務" + taskId + "執行完畢");});
}executor.shutdown(); // 關閉線程池

5.2 提交Callable任務

ExecutorService executor = Executors.newFixedThreadPool(3);Future<String> future = executor.submit(() -> {Thread.sleep(2000);return "任務執行結果";
});try {String result = future.get(); // 獲取任務結果System.out.println("結果: " + result);
} catch (InterruptedException | ExecutionException e) {e.printStackTrace();
}executor.shutdown();

5.3 定時任務

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);// 延遲3秒后執行任務
scheduler.schedule(() -> {System.out.println("延遲任務執行");
}, 3, TimeUnit.SECONDS);// 延遲1秒后開始執行,每2秒執行一次
scheduler.scheduleAtFixedRate(() -> {System.out.println("定時任務執行");
}, 1, 2, TimeUnit.SECONDS);

六、線程池的拒絕策略

6.1 AbortPolicy(默認)

直接拋出RejectedExecutionException異常:

new ThreadPoolExecutor.AbortPolicy()

6.2 CallerRunsPolicy

由提交任務的線程自己執行該任務:

new ThreadPoolExecutor.CallerRunsPolicy()

6.3 DiscardPolicy

直接丟棄任務,不做任何處理:

new ThreadPoolExecutor.DiscardPolicy()

6.4 DiscardOldestPolicy

丟棄任務隊列中最老的任務,然后嘗試提交新任務:

new ThreadPoolExecutor.DiscardOldestPolicy()

七、線程池的監控與調優

7.1 監控線程池狀態

ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>()
);// 獲取線程池狀態
int activeCount = executor.getActiveCount(); // 活躍線程數
long completedTaskCount = executor.getCompletedTaskCount(); // 已完成任務數
int queueSize = executor.getQueue().size(); // 隊列中的任務數

7.2 合理配置線程池大小

  • CPU密集型任務:線程數 = CPU核心數 + 1
  • IO密集型任務:線程數 = CPU核心數 * (1 + 平均等待時間/平均處理時間)

八、線程池的最佳實踐

8.1 避免使用Executors工廠方法

Executors提供的工廠方法可能會創建出有資源耗盡風險的線程池,建議直接使用ThreadPoolExecutor構造函數:

ExecutorService executor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS,new LinkedBlockingQueue<>(100),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy()
);

8.2 正確關閉線程池

executor.shutdown(); // 平緩關閉,等待已提交任務執行完畢
// executor.shutdownNow(); // 立即關閉,嘗試終止正在執行的任務try {if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {executor.shutdownNow();}
} catch (InterruptedException e) {executor.shutdownNow();
}

8.3 使用自定義線程工廠

通過自定義線程工廠可以為線程設置有意義的名稱,便于調試:

ThreadFactory namedThreadFactory = new ThreadFactory() {private final AtomicInteger threadNum = new AtomicInteger(1);@Overridepublic Thread newThread(Runnable r) {return new Thread(r, "my-thread-" + threadNum.getAndIncrement());}
};

若這篇內容幫到你,動動手指支持下!關注不迷路,干貨持續輸出!
ヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノ

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

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

相關文章

解碼美元-黃金負相關:LSTM-Attention因果發現與黃金反彈推演

摘要&#xff1a;本文采用時間序列分析框架與自然語言處理&#xff08;NLP&#xff09;技術&#xff0c;對黃金與美元指數的負相關關系進行量化拆解。通過構建包含宏觀經濟因子、市場情緒指標及地緣風險的三維分析模型&#xff0c;揭示當前貴金屬市場的核心驅動邏輯&#xff0c…

Asp.Net Core SignalR導入數據

文章目錄 前言一、安裝包二、使用步驟1.實現SignalR Hub服務&#xff1a;2.實現CSV文件解析及數據導入服務3.控制器4.前端實現&#xff08;vue&#xff09; 三、關鍵技術點說明總結 前言 導入CSV文件中的數據到數據庫&#xff0c;使用CsvHelper解析CSV文件&#xff0c;SqlBulk…

Modern C++(四)聲明

4、聲明 聲明是將名字引入到cpp程序中&#xff0c;不是每條聲明都聲明實際的東西。定義是足以使該名字所標識的實體被使用的聲明。聲明包含以下幾種&#xff1a; 函數定義模板聲明模板顯式實例化模板顯式特化命名空間定義鏈接說明屬性聲明&#xff08;C11&#xff09;空聲明&…

目標檢測yolo算法

yolov5s&#xff1a; 從github官網下載yolov5的算法之后&#xff0c;配置好環境&#xff08;pycharm安裝包-CSDN博客&#xff09;&#xff0c;再下載權重文件&#xff0c;比如默認的yolov5s.pt&#xff1b; 運行當前文件&#xff08;detect.py&#xff09;&#xff0c;就能看…

一個超強的推理增強大模型,開源了,本地部署

大家好&#xff0c;我是 Ai 學習的老章 前幾天介紹了MOE 模型先驅 Mistral 開源的代碼 Agent 大模型——mistralai/Devstral-Small-2505 今天一起看看 Mistral 最新開源的推理大模型——Magistral Magistral 簡介 Mistral 公司推出了首個推理模型 Magistral 及自研可擴展強…

MySQL體系架構解析(五):讀懂MySQL日志文件是優化與故障排查的關鍵

MySQL文件 日志文件 在服務器運行過程中&#xff0c;會產生各種各樣的日志&#xff0c;比如常規的查詢日志&#xff0c;錯誤日志、二進制日志、 redo 日志和 Undo 日志等&#xff0c;日志文件記錄了影響 MySQL 數據庫的各種類型活動。 常見的日志文件有&#xff1a;錯誤日志…

湖南省網絡建設與運維賽項競賽規程及樣題

湖南省職業院校技能競賽樣題 賽題說明 一、競賽內容 “網絡建設與運維”競賽共分三個部分&#xff0c;其中&#xff1a; 第一部分&#xff1a;職業規范與素養 &#xff08; 5 分&#xff09; 第二部分&#xff1a;網絡搭建及安全部署項目 &#xff08; 50 分&#xff09…

華為云Flexus+DeepSeek征文 | 基于華為云ModelArts Studio搭建AnythingLLM聊天助手

華為云FlexusDeepSeek征文 | 基于華為云ModelArts Studio搭建AnythingLLM聊天助手 引言一、ModelArts Studio平臺介紹華為云ModelArts Studio簡介ModelArts Studio主要特點 二、AnythingLLM介紹AnythingLLM 簡介AnythingLLM主要特點AnythingLLM地址 三、安裝AnythingLLM應用下載…

板凳-------Mysql cookbook學習 (十--5)

6.11 計算年齡 2025年6月11日星期三 --創建表、初始化數據 drop table if exists sibling; create table sibling (name char(20),birth date );insert into sibling (name,birth) values(Gretchen,1942-04-14); insert into sibling (name,birth) values(Wilbur,1946-11-28)…

SAP RESTFUL接口方式發布SICF實現全路徑

其他相關資料帖可參考&#xff1a; https://blog.csdn.net/woniu_maggie/article/details/146210752 https://blog.csdn.net/SAPmatinal/article/details/134349125 https://blog.csdn.net/weixin_44382089/article/details/128283417 【業務場景】 外部系統不想通過RFC (需…

在windows中安裝或卸載nginx

首先在nginx的安裝目錄下cmd查看nginx的版本&#xff1a; 在看windows的服務中是否nginx注冊為服務了 如果注冊了服務就先將服務卸載了 在nginx的安裝目錄cmd執行命令 NginxService.exe uninstall “NginxService”是對應的注冊的服務名稱 關閉所有的相關nginx的服務這個也…

FaceFusion 技術深度剖析:核心算法與實現機制揭秘

在 AI 換臉技術蓬勃發展的浪潮中&#xff0c;FaceFusion 憑借其出色的換臉效果和便捷的操作&#xff0c;成為眾多用戶的首選工具。從短視頻平臺上的創意惡搞視頻&#xff0c;到影視制作中的特效合成&#xff0c;FaceFusion 都展現出強大的實用性。而這一切的背后&#xff0c;是…

2. Web網絡基礎 - 協議端口

深入解析協議端口與netstat命令&#xff1a;網絡工程師的實戰指南 在網絡通信中&#xff0c;協議端口是服務訪問的門戶。本文將全面解析端口概念&#xff0c;并通過netstat命令實戰演示如何監控網絡連接狀態。 一、協議端口核心知識解析 1. 端口號的本質與分類 端口范圍類型說…

嵌入式學習筆記 - freeRTOS vTaskPlaceOnEventList()函數解析

vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); 函數第一個參數為消息隊列等待插入鏈表&#xff0c; void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) { configASSERT( pxEventList ); /…

Ubuntu 配置使用 zsh + 插件配置 + oh-my-zsh 美化過程

Ubuntu 配置使用 zsh 插件配置 oh-my-zsh 美化過程 引言zsh 安裝及基礎配置oh-my-zsh 安裝及美化配置oh-my-zsh 安裝主題美化配置主題自定義主題 插件安裝及配置官方插件查看及啟用插件安裝 主題文件備份.zshrcre5et_self.zsh-theme 同步發布在個人筆記Ubuntu 配置使用 zsh …

Xilinx FPGA 重構Multiboot ICAPE2和ICAPE3使用

一、FPGA Multiboot 本文主要介紹基于IPROG命令的FPGA多版本重構&#xff0c;用ICAP原語實現在線多版本切換。需要了解MultiBoot Fallback點擊鏈接。 如下圖所示&#xff0c;ICAP原語可實現flash中n1各版本的動態切換&#xff0c;在工作過程中&#xff0c;可以通過IPROG命令切…

springMVC-11 中文亂碼處理

前言 本文介紹了springMVC中文亂碼的解決方案&#xff0c;同時也貼出了本人遇到過的其他亂碼情況&#xff0c;可以根據自身情況選擇合適的解決方案。 其他-jdbc、前端、后端、jsp亂碼的解決 Tomcat導致的亂碼解決 自定義中文亂碼過濾器 老方法&#xff0c;通過javaW…

mysql-innoDB存儲引擎事務的原理

InnoDB 存儲引擎支持 ACID 事務&#xff0c;其事務機制是通過 Redo Log&#xff08;重做日志&#xff09;、Undo Log&#xff08;回滾日志&#xff09; 和 事務日志系統 來實現的。下面詳細解析 InnoDB 事務的工作原理。 1.事務的基本特性&#xff08;ACID&#xff09; 特性描…

在GIS 工作流中實現數據處理

通過將 ArcPy 應用于實際的 GIS 工作流&#xff0c;我們可以高效地完成數據處理任務&#xff0c;節省大量時間和精力。接下來&#xff0c;本文將結合具體案例&#xff0c;詳細介紹如何運用 ArcPy 實現 GIS 數據處理的全流程。 數據讀取與合并 假設我們有多個 shapefile 文件&a…

第十四屆藍橋杯_省賽B組(C).冶煉金屬

題目如下: 拿到題我們來看一下&#xff0c;題目的意思&#xff0c;就是求出N個記錄中的最大最小值&#xff0c;言外之意就是&#xff0c;如果超過了這個最大值不行&#xff0c;如果小于這個最小值也不行&#xff0c;所以我們得出&#xff0c;這道題是一個二分答案的題目&#x…