高薪程序員必修課-Java中為什么不建議使用Executors來創建線程池?

目錄

前言

原因分析

1. newFixedThreadPool 和 newSingleThreadExecutor

示例:

2. newCachedThreadPool

示例:

建議的替代方法

示例:

解釋:

總結


前言

????????在Java中,Executors 類提供了幾個工廠方法來創建不同類型的線程池,例如 newFixedThreadPoolnewCachedThreadPoolnewSingleThreadExecutor。雖然這些方法方便使用,但它們在某些情況下可能會帶來潛在的問題,因此不建議在生產環境中直接使用 Executors 來創建線程池。下面從原理角度詳細講解原因,并提供相應的示例。

原因分析

1. newFixedThreadPoolnewSingleThreadExecutor

原理:這兩個方法使用無界隊列 LinkedBlockingQueue 作為任務隊列。

問題:無界隊列意味著隊列可以無限增長。如果任務提交速度快于任務處理速度,隊列中的任務會不斷增加,可能導致內存耗盡(OOM)。

示例:
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < Integer.MAX_VALUE; i++) {executor.submit(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {Thread.currentThread().interrupt();}});
}

在這個示例中,如果任務提交速度非常快,任務會無限制地排隊,最終導致內存耗盡。

2. newCachedThreadPool

原理:該方法使用 SynchronousQueue 作為任務隊列,并且線程池的最大線程數是 Integer.MAX_VALUE

問題SynchronousQueue 不存儲任務,每個插入操作必須等待相應的移除操作。如果任務提交速度快于任務處理速度,會創建大量線程,可能導致系統資源耗盡(如CPU、內存等)。

示例:
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < Integer.MAX_VALUE; i++) {executor.submit(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {Thread.currentThread().interrupt();}});
}

在這個示例中,如果任務提交速度非常快,會創建大量線程,最終導致系統資源耗盡。

建議的替代方法

為了更好地控制線程池的行為,建議使用 ThreadPoolExecutor 構造函數來創建線程池。這樣可以更明確地指定線程池的參數,如核心線程數、最大線程數、任務隊列類型和拒絕策略。

示例:
import java.util.concurrent.*;public class CustomThreadPoolExample {public static void main(String[] args) {// 創建一個具有自定義參數的線程池ThreadPoolExecutor executor = new ThreadPoolExecutor(10,                        // 核心線程數20,                        // 最大線程數60L,                       // 非核心線程的空閑時間TimeUnit.SECONDS,          // 空閑時間的單位new ArrayBlockingQueue<>(100),  // 有界任務隊列new ThreadPoolExecutor.CallerRunsPolicy() // 拒絕策略);for (int i = 0; i < 200; i++) {executor.submit(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println(Thread.currentThread().getName() + " completed task");});}executor.shutdown();}
}
解釋:
  1. 核心線程數和最大線程數

    • 核心線程數設置為10,最大線程數設置為20。
    • 線程池在初始時創建10個核心線程,任務提交超過10個時,會創建最多10個額外的線程(最大線程數-核心線程數)。
  2. 非核心線程的空閑時間

    • 非核心線程空閑時間設置為60秒,超過這個時間未處理任務的非核心線程將被終止。
  3. 有界任務隊列

    • 使用 ArrayBlockingQueue,容量為100。這限制了任務隊列的大小,避免無限增長導致內存耗盡。
  4. 拒絕策略

    • 使用 CallerRunsPolicy 作為拒絕策略。當任務隊列已滿且所有線程都在運行時,拒絕策略將任務返回給調用者線程執行,避免任務丟失。

總結

不建議使用 Executors 創建線程池的原因主要是它隱藏了線程池的具體實現,容易導致以下問題:

  1. 無界隊列導致內存耗盡newFixedThreadPoolnewSingleThreadExecutor 使用無界隊列,可能導致內存耗盡。
  2. 線程無限增長導致資源耗盡newCachedThreadPool 使用 SynchronousQueue 和無限制的最大線程數,可能導致系統資源耗盡。

使用 ThreadPoolExecutor 構造函數可以更精細地控制線程池的參數,從而避免這些潛在問題。

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

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

相關文章

RAG開源項目Qanything源碼閱讀3-在線推理

原文&#xff1a;前沿重器[47] | RAG開源項目Qanything源碼閱讀3-在線推理 項目&#xff1a;https://github.com/netease-youdao/QAnything 第一篇&#xff1a;RAG開源項目Qanything源碼閱讀1-概述服務 第二篇&#xff1a;RAG開源項目Qanything源碼閱讀2-離線文件處理 0&#x…

Pytest+Allure+Yaml+PyMsql+Jenkins+Gitlab接口自動化(五)Jenkins配置

一、背景 Jenkins&#xff08;本地宿主機搭建&#xff09; 拉取GitLab(服務器)代碼到在Jenkins工作空間本地運行并生成Allure測試報告 二、框架改動點 框架主運行程序需要先注釋掉運行代碼&#xff08;可不改&#xff0c;如果運行報allure找不到就直接注釋掉&#xff09; …

中英雙語介紹美國的州:路易斯安那州(Louisiana)

中文版 路易斯安那州簡介 路易斯安那州位于美國南部&#xff0c;以其豐富的歷史文化、多樣的自然景觀和獨特的音樂和美食傳統而聞名。以下是對路易斯安那州的詳細介紹&#xff0c;包括其地理位置、人口、經濟、教育、文化和主要城市。 地理位置 路易斯安那州東臨密西西比州…

鴻蒙應用開發-時間屏幕

點擊下載源碼&#xff1a; https://download.csdn.net/download/liuhaikang/89509449 做一個時間屏幕&#xff0c;可以點擊切換白色和黑色&#xff0c;有漸變效果&#xff0c;使用到了鴻蒙的動畫效果。 在這個設計中&#xff0c;我們首先引入了通用能力包&#xff0c;以實現功…

Kubernetes 離線安裝的坑我采了

Kubernetes 離線安裝的坑我采了 一、Error from server: Get "https://xx.xx.xx.xx:10250/containerLogs/kube-system/calico-node-8dnvs/calico-node": tls: failed to verify certificate: x509: certificate signed by unknown authority二、calico 或 pod 啟動正…

cesium公交車軌跡漫游

個人博客&#xff1a;CSDN 博客-滿分觀察網友 z 演示地址&#xff1a;嗶哩嗶哩-滿分觀察網友 z 這是一個用 Cesium.js 做的公交車軌跡漫游&#xff0c;實現的功能有加載站點和道路軌跡點數據、監聽車輛的實時位置、車輛控制器。滾動屏等等。 文章目錄 1. 地圖初始化2. 數據渲…

【高中數學/基本不等式】已知:x,y均為正實數,且xy+2x+y=4 求:x+y的最小值?

【問題】 已知&#xff1a;x,y均為正實數&#xff0c;且xy2xy4 求&#xff1a;xy的最小值&#xff1f; 【來源】 https://www.ixigua.com/7147585275823292942?logTagf25494de7fce23a3a3d0 【解答】 解&#xff1a; 由xy2xy4 兩邊加二得 xy2xy24 2 分解因式得 (x1)(…

0090__【Git系列】merge和rebase的區別

【Git系列】merge和rebase的區別_rebase和merge的區別-CSDN博客 git中rebase和merge的區別是什么-git-PHP中文網 https://blog.51cto.com/qzcsbj/9444199

從零搭建教育管理系統:Java + Vue.js 教學-02

第三步:創建實體類和 Mapper 接口 現在我們已經設計好了數據庫表,接下來使用 MyBatis-Plus 將這些表映射到 Java 對象,以便在代碼中輕松地進行操作。 1. 創建實體類 在 src/main/java/<your_package>/entity 目錄下 (如果沒有該目錄,請手動創建),創建與數據庫表對應…

MyBatis(20)MyBatis 事務管理如何實現

MyBatis 的事務管理是通過底層 JDBC 連接的事務管理機制來實現的。事務管理對于任何涉及多個數據庫操作的應用程序來說都是至關重要的&#xff0c;它確保數據的一致性和完整性。在 MyBatis 中&#xff0c;事務管理可以通過 SQL 會話&#xff08;SqlSession&#xff09;來實現。…

【WEB前端2024】3D智體編程:喬布斯3D紀念館-第53課-語音指令跳舞

【WEB前端2024】3D智體編程&#xff1a;喬布斯3D紀念館-第53課-語音指令跳舞 使用dtns.network德塔世界&#xff08;開源的智體世界引擎&#xff09;&#xff0c;策劃和設計《喬布斯超大型的開源3D紀念館》的系列教程。dtns.network是一款主要由JavaScript編寫的智體世界引擎&…

可信計算的完整專用名詞列表

可信計算的完整專用名詞列表 Trusted Computing - 可信計算Trusted Platform Module (TPM) - 可信平臺模塊Hardware Root of Trust - 硬件根信任Secure Boot - 安全啟動Remote Attestation - 遠程證明Integrity Measurement - 完整性度量Measurement Log - 度量日志Attestatio…

Android 圖像效果的奧秘

在當今數字化時代&#xff0c;圖像已經成為人們生活和工作中不可或缺的一部分。而在 Android 系統中&#xff0c;圖像效果的應用更是豐富多彩&#xff0c;為用戶帶來了更加出色的視覺體驗。本文將深入探討 Android 圖像效果的原理、實現方法以及應用場景&#xff0c;幫助讀者更…

面試題springboot面試

文章目錄 Spring的依賴注入構造器注入stetter注入屬性注入 springboot的優勢第一開箱即用約定大于配置內嵌tomcat服務器 javaweb的三大組件springboot的自動配置原理SpringIoc的實現機制springmvcspring如何簡化開發 Spring的依賴注入 構造器注入 stetter注入 屬性注入 使用…

按位異或^

在 Python 中&#xff0c;a ^ b 表示按位異或運算符。按位異或運算符對整數的每一位進行運算&#xff0c;如果對應位上的兩個二進制數字不同&#xff0c;則結果為 1&#xff0c;否則為 0。 示例 a 5 # 二進制: 0101 b 3 # 二進制: 0011result a ^ b print(result) # 輸…

私域流量:塑造企業數字營銷的未來

在當今數字化的時代&#xff0c;流量成為了商業世界中的新貨幣&#xff0c;而“私域流量”更是其中的黃金。但“私域流量”究竟是什么&#xff1f;它如何成為企業數字化轉型和營銷策略中不可或缺的一部分&#xff1f;本文將探討私域流量的概念&#xff0c;并通過案例分析其運營…

前端進階:Vue.js

目錄 框架&#xff1a; 助解&#xff1a; 框架&#xff1a; VUE 什么是Vue.js? Vue.js優點 Vue安裝 方式一&#xff1a;直接用<script>引入 方式二&#xff1a;命令行工具 第一個Vue程序 代碼 代碼解釋&#xff1a; 運行 Vue指令 v-text v-html v-tex…

Mysql和ES使用匯總

一、mysql和ES在業務上的配合使用 一般使用時使用ES 中存儲全文檢索的關鍵字與獲取的商品詳情的id&#xff0c;通過ES查詢獲取查詢商品的列表中展示的數據&#xff0c;通過展示id 操作去獲取展示商品的所有信息。mysql根據id去查詢數據庫數據是很快的&#xff1b; 為什么ES一般…

JavaScript如何聲明json對象

在JavaScript中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;對象實際上是以JavaScript對象的形式表示的。JSON是一種輕量級的數據交換格式&#xff0c;它基于ECMAScript&#xff08;歐洲計算機協會制定的js規范&#xff09;的一個子集&#xff0c;采用…

10 - Python文件編程和異常

文件和異常 在實際開發中&#xff0c;常常需要對程序中的數據進行持久化操作&#xff0c;而實現數據持久化最直接簡單的方式就是將數據保存到文件中。說到“文件”這個詞&#xff0c;可能需要先科普一下關于文件系統的知識&#xff0c;對于這個概念&#xff0c;維基百科上給出…