Java編程基本功大揭秘 | 詳解深入分析Java線程池源碼和底層原理,掌握實戰技巧【1】

詳解深入分析Java線程池源碼和底層原理

  • 文章大綱
  • 引言
    • Java線程池概念及重要性
  • `ThreadPoolExecutor`類的概述
    • `ThreadPoolExecutor`類的基本功能和作用
      • **基本功能**
      • **核心作用**
    • `ThreadPoolExecutor`主要構造函數及其參數
      • 繼承關系鏈
      • 功能介紹
      • ThreadPoolExecutor 構造器
        • 構造器參數
          • 構造器中各個參數的含義
            • corePoolSize
            • maximumPoolSize
            • keepAliveTime
            • unit
            • workQueue
            • threadFactory
            • handler
      • 接口繼承關系鏈
  • 總結與展望

文章大綱

在這里插入圖片描述

引言

早期的編程實踐中,直接使用新線程執行任務雖直觀且易實現,但在高并發場景下卻面臨性能瓶頸。當系統需處理大量短暫并發任務時,頻繁創建和銷毀線程會導致巨大的開銷,降低系統性能,甚至可能因資源過度消耗導致系統崩潰。為解決線程頻繁創建和銷毀的問題,我們需要高效復用線程的機制。

Java線程池概念及重要性

Java的線程池(Thread Pool)提供了這樣的解決方案:預先創建并管理線程組,任務執行時從池中獲取線程,任務完成后線程返回池中等待新任務。這種方式顯著減少線程創建和銷毀,大幅提升系統并發處理能力。


ThreadPoolExecutor類的概述

Java中的ThreadPoolExecutor是線程池的核心實現,提供靈活的配置和管理方法。要深入理解其工作原理和使用,可從關鍵方法入手,逐步探索其實現邏輯。

ThreadPoolExecutor類的基本功能和作用

在Java中,ThreadPoolExecutor是線程池框架的核心組件,它允許開發者以高度可配置和靈活的方式管理線程資源。其核心功能是為應用程序提供一個線程池,從而優化和控制線程的使用,特別是在處理大量并發任務時。

基本功能

  1. 線程管理與復用ThreadPoolExecutor管理一個線程池,當任務提交給線程池時,線程池會嘗試復用已有的線程來執行任務,而不是為每個新任務都創建一個新線程。這大大減少了線程創建和銷毀的開銷。
  2. 任務隊列:當線程池中的線程都在忙碌時,新提交的任務會被放置在一個任務隊列中等待執行。ThreadPoolExecutor允許你配置這個隊列的大小和類型,以適應不同的應用場景。
  3. 線程生命周期管理ThreadPoolExecutor允許你配置線程的生命周期,包括核心線程數、最大線程數、線程空閑時間等。當線程空閑超過指定時間后,多余的線程會被銷毀以節省資源。
  4. 任務拒絕策略:當任務隊列已滿且所有線程都在忙碌時,新提交的任務將被拒絕。ThreadPoolExecutor提供了幾種內置的任務拒絕策略,同時也允許你自定義拒絕策略。

核心作用

  1. 提高性能:通過復用線程,ThreadPoolExecutor顯著減少了線程創建和銷毀的開銷,從而提高了應用程序的性能。
  2. 資源管理ThreadPoolExecutor允許你精細控制線程資源的使用,包括線程的數量、任務的排隊策略等,從而更有效地管理系統的資源。
  3. 簡化并發編程:使用ThreadPoolExecutor,開發者可以更加專注于業務邏輯的實現,而無需過多關注線程的管理和調度。
  4. 提供靈活的擴展性:通過調整線程池的配置參數,ThreadPoolExecutor可以適應不同規模和需求的應用程序,提供了很好的擴展性。

ThreadPoolExecutor主要構造函數及其參數

繼承關系鏈

在這里插入圖片描述

ThreadPoolExecutor 實現了 ExecutorService 接口, ExecutorService 擴展了 Executor 接口。

功能介紹

  • Executor:這是Java中執行已提交任務的對象的接口,提供了一種將任務與任務執行機制(通常是線程)解耦的方式。

  • ExecutorService:這是一個擴展了Executor接口的接口,它提供了更全面的生命周期管理(例如關閉、終止)和任務提交機制(例如execute, submit等)。ExecutorService通常用于控制和管理線程,它內部封裝了一組線程,使得線程的使用更加簡便和安全。

  • AbstractExecutorService:實際上,Java標準庫中沒有名為AbstractExecutorService的接口。可能您是想引用一個抽象類,但ExecutorService接口本身通常被具體類(如ThreadPoolExecutor)實現,而不是由抽象類來擴展。在標準庫中,有一個AbstractExecutorService類的可能性很低,但如果有這樣的類,它可能提供了一些ExecutorService接口的默認實現。

  • ThreadPoolExecutor:這是一個實現了ExecutorService接口的具體類,它提供了線程池的實現,允許用戶配置核心線程數、最大線程數、線程空閑時間、任務隊列等參數。ThreadPoolExecutor是線程池框架中最常用的實現之一,它高效地管理線程資源的復用,降低了系統的開銷。

ThreadPoolExecutor 構造器

java.uitl.concurrent.ThreadPoolExecutor類是線程池中最核心的一個類,因此如果要透徹地了解Java中的線程池,必須先了解這個類。下面我們來看一下ThreadPoolExecutor類的具體實現源碼。

public class ThreadPoolExecutor extends AbstractExecutorService {public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue);public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit 	unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
...
}	

從上面的代碼可以得知,ThreadPoolExecutor繼承了AbstractExecutorService類,并提供了四個構造器,事實上,通過觀察每個構造器的源碼具體實現,發現前面三個構造器都是調用的第四個構造器進行的初始化工作。

構造器參數

了解如何配置線程池。這包括設置核心線程數、最大線程數、隊列容量等參數。這些參數的選擇將直接影響線程池的性能和穩定性。通過合理地配置這些參數,我們可以在保證系統性能的同時,也避免了資源的過度消耗。

構造器中各個參數的含義

在這里插入圖片描述

corePoolSize

corePoolSize 是線程池中的一個關鍵參數,它決定了線程池中的核心線程數量。

在創建線程池后,初始狀態下線程池內部并不包含任何線程。線程池會等待任務的到來,并根據需要創建線程來執行任務。除非顯式地調用 prestartAllCoreThreads()prestartCoreThread() 方法,線程池才會預先創建核心線程。從這兩個方法的名字就可以推斷出,它們的目的是在未接收到任務之前就創建指定數量的線程。

在默認情況下,當第一個任務到達時,線程池會創建一個新線程來執行它。隨著更多任務的到達,線程池中的線程數量會逐漸增加,直到達到 corePoolSize 所設定的數量。一旦線程池中的線程數量達到這個核心值,后續到達的任務將不再觸發新線程的創建。

此時,如果還有新任務到來,線程池會將它們放入一個緩存隊列中等待執行。這個隊列通常是一個阻塞隊列,用于存儲待執行的任務。只有當隊列滿了,或者線程池中的線程數量低于 maximumPoolSize(最大線程池大小)時,線程池才會考慮創建額外的線程來執行任務。

注意:合理配置 corePoolSize,可以平衡線程創建和銷毀的開銷與任務執行的效率。如果 corePoolSize 設置得太小,可能會導致大量任務在隊列中等待,從而增加任務的延遲;如果設置得太大,又可能浪費系統資源,因為不是所有線程都會同時處于忙碌狀態。因此,在實際應用中,需要根據任務的特性和系統資源來合理設置這個參數。

maximumPoolSize

線程池中的maximumPoolSize參數指的是線程池能夠容納的最大線程數量。當線程池中的線程數量達到這個值時,新的任務提交到線程池時,線程池將不會再創建新的線程來處理這些任務,而是根據線程池的其他策略(如隊列策略)來決定如何處理這些新任務。

keepAliveTime

線程沒有任務執行時最多保持多久時間會終止。

默認情況下,只有當線程池中的線程數大于corePoolSize時,keepAliveTime才會起作用,直到線程池中的線程數不大于corePoolSize,即當線程池中的線程數大于corePoolSize時,如果一個線程空閑的時間達到keepAliveTime,則會終止,直到線程池中的線程數不超過corePoolSize。

注意:如果調用了allowCoreThreadTimeOut(boolean)方法,在線程池中的線程數不大于corePoolSize時,keepAliveTime參數也會起作用,直到線程池中的線程數為0;

unit

unit:參數keepAliveTime的時間單位,有7種取值,在TimeUnit類中有7種靜態屬性:
在這里插入圖片描述

workQueue

一個阻塞隊列,用來存儲等待執行的任務,這個參數的選擇也很重要,會對線程池的運行過程產生重大影響,一般來說,這里的阻塞隊列有以下幾種選擇:
在這里插入圖片描述
線程池中的阻塞隊列(BlockingQueue)是線程池的一個重要組成部分,用于存儲待執行的任務。當線程池中的線程數量達到corePoolSize時,新提交的任務會被放入這個隊列中等待執行。阻塞隊列的類型會影響線程池的行為和性能。以下是您提到的幾種阻塞隊列的作用和特性:

  • ArrayBlockingQueue(數組類型隊列)

    • 特點:基于數組結構的有界阻塞隊列。
    • 容量限制:在創建時需要指定隊列的容量,一旦隊列滿了,新提交的任務會被拒絕。
    • 性能:由于是基于數組,它在入隊和出隊操作上的時間復雜度是O(1),具有較好的性能。
    • 使用場景:適用于有固定大小的任務緩存場景,當任務量比較大時,能夠避免在內存中創建大量的對象。
  • LinkedBlockingQueue(鏈表類型隊列)

    • 特點:基于鏈表結構的有界(但默認大小為Integer.MAX_VALUE,可視為無界)阻塞隊列。
    • 容量限制:可以指定隊列的容量,但如果不指定,則默認為Integer的最大值,幾乎可以認為是無界的。
    • 性能:入隊和出隊操作的時間復雜度為O(1),但由于是鏈表結構,實際性能可能會略低于ArrayBlockingQueue。
    • 使用場景:適用于任務量較大,但不想或不需要限制隊列大小的場景。
  • SynchronousQueue(同步單元素隊列)

    • 特點:一個不存儲元素的阻塞隊列,也就是說它的容量為1。
    • 容量限制:只能存儲一個元素,如果隊列中有元素,則新提交的任務可以直接獲取執行,否則需要等待其他線程執行完任務后,騰出空間才能繼續。
    • 性能:入隊和出隊操作的時間復雜度接近O(1),但由于其特殊的特性,線程間的交互更為頻繁,可能導致更高的線程調度開銷。
    • 使用場景:適用于線程池中的線程數量與任務數量大致相等,且任務執行時間較短的場景。
  • PriorityBlockingQueue(具有優先級的隊列)

    • 特點:一個支持優先級排序的無界阻塞隊列。
    • 容量限制:默認是無界的,可以存儲任意數量的任務。
    • 優先級:隊列中的元素按照它們的自然排序或者通過提供的Comparator進行排序,優先級高的任務將優先被執行。
    • 性能:由于需要排序,入隊和出隊操作的時間復雜度可能會高于O(1)。
    • 使用場景:適用于需要按照優先級執行任務的場景,例如,某些重要或緊急的任務需要優先得到處理。

ArrayBlockingQueue和PriorityBlockingQueue使用較少,一般使用LinkedBlockingQueue和Synchronous。線程池的排隊策略與BlockingQueue有關。

threadFactory

線程工廠,主要用來創建線程的工廠實現類

public interface ThreadFactory {/*** Constructs a new {@code Thread}.  Implementations may also initialize* priority, name, daemon status, {@code ThreadGroup}, etc.** @param r a runnable to be executed by new thread instance* @return constructed thread, or {@code null} if the request to*         create a thread is rejected*/Thread newThread(Runnable r);
}
handler

表示當拒絕處理任務時的策略,有以下四種取值:
在這里插入圖片描述

接口繼承關系鏈

總結與展望

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

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

相關文章

c語言自動售貨機

C語言編寫的自動售貨機程序可以模擬真實自動售貨機的基本功能&#xff0c;例如選擇商品、顯示價格、付款和找零。下面是一個簡單的示例代碼&#xff0c;展示了一個基本的自動售貨機程序&#xff1a; #include <stdio.h>// 商品結構體 typedef struct {char name[30];int…

破解對LabVIEW的偏見

LabVIEW被廣泛應用于科學研究、工程測試和自動化控制領域&#xff0c;具有專業性和高效的開發能力。盡管有人對其存在偏見&#xff0c;認為不如C語言&#xff0c;但LabVIEW的圖形化編程、強大集成能力、豐富社區支持和專業功能&#xff0c;使其在許多實際應用中表現出色。通過多…

Go語言環境安裝

Go下載地址 哪個能用用哪個。 https://go.dev/ https://golang.google.cn/&#xff08;Golang官網的官方鏡像&#xff09; Windows 使用.msi安裝包安裝 下載msi文件 安裝 雙擊運行go1.22.4.windows-amd64.msi Next 勾選I accept the terms in the License Agreement&…

收藏 | SSL證書無效的原因和解決辦法

當瀏覽器訪問一個使用SSL證書保護的網站時&#xff0c;會檢查其證書的有效性。如果發現證書存在問題&#xff0c;瀏覽器會顯示“SSL證書無效”的警告信息&#xff0c;提醒用戶存在潛在的安全風險。 “SSL證書無效”的警告可能會導致用戶離開站點&#xff08;并且永遠不會返回&…

MySQL高級-SQL優化-小結

文章目錄 1、insert 優化2、主鍵優化3、order by 優化4、group by 優化5、limit 優化6、count 優化7、update 優化 1、insert 優化 insert&#xff1a;批量插入、手動控制事務、主鍵順序插入 大批量插入&#xff1a;load data local infile 2、主鍵優化 主鍵長度盡量短、順序插…

系統漏洞復現與勒索病毒

知識點&#xff1a;SMB漏洞介紹、漏洞復現流程、勒索病毒攻擊與防護 滲透測試相關&#xff1a; 基本概念&#xff1a; 滲透測試就是利用我們所掌握的滲透知識&#xff0c;對網站進行一步一步的滲透&#xff0c;發現其中存在的漏洞和隱藏的風險&#xff0c;然后撰寫一篇測試報…

FastAPI教程I

本文參考FastAPI教程https://fastapi.tiangolo.com/zh/tutorial 第一步 import uvicorn from fastapi import FastAPIapp FastAPI()app.get("/") async def root():return {"message": "Hello World"}if __name__ __main__:uvicorn.run(&quo…

GPT-4o模型到底有多強

近年來&#xff0c;人工智能技術突飛猛進&#xff0c;在自然語言處理&#xff08;NLP&#xff09;和計算機視覺等領域取得了令人矚目的成就。OpenAI推出的GPT-4o模型作為最新一代的語言模型&#xff0c;進一步提升了AI的能力&#xff0c;尤其在文檔分析、識圖生文、文生圖等功能…

elementUI的搭建使用過程

Element - The worlds most popular Vue UI framework 上面是elementUI的網站,進入網站 點擊右上角的組件按鈕 復制這段代碼到你的項目終端:npm i element-ui -S 加載完成后即可使用elementUI網站中的組件,使用它們只需要復制組件下面的代碼即可

Unity UGUI 實現簡單兩點連線功能

實現 記錄鼠標點擊位置為線段起點。 posStart Input.mousePosition; 創建一個Image 作為線段。 line new GameObject("line"); rtLine line.AddComponent<RectTransform>(); rtLine.pivot new Vector2(0, 0.5f); rtLine.localScale Vector3.one; img…

Linux 進程通信

1.什么是進程通信&#xff1f; 答&#xff1a;兩個或多個進程實現數據層面的交互&#xff1b;但是因為進程的獨立性&#xff0c;導致進程通信的成本較高&#xff1b; 2.為什么要通信&#xff1f; 答&#xff1a;多進程之間由協同的需求&#xff0c;所以通信&#xff1b;以下…

Java常用對象的快速初始化

在Java中&#xff0c;有多種方式來快速初始化各種常用對象&#xff0c;如字符串數組&#xff08;String[]&#xff09;&#xff0c;集合列表&#xff08;List&#xff09;&#xff0c;映射表&#xff08;Map&#xff09;&#xff0c;以及集合&#xff08;Set&#xff09;。不同…

動態服務管理的藝術:Eureka在服務擴展與收縮中的策略

動態服務管理的藝術&#xff1a;Eureka在服務擴展與收縮中的策略 在微服務架構中&#xff0c;服務的動態擴展和收縮是實現高可用性和彈性的關鍵。Eureka&#xff0c;作為Netflix開源的服務發現框架&#xff0c;提供了一套機制來處理服務實例的動態變化。本文將深入探討Eureka如…

在操作系統中,background通常指的是運行于后臺的進程或任務

在計算機中&#xff0c;"background"一詞具有多種含義&#xff0c;以下是一些主要的解釋和相關信息&#xff1a; 計算機視覺中的背景&#xff08;Background&#xff09;&#xff1a; 在計算機視覺中&#xff0c;background指的是圖像或視頻中的背景部分&#xff0c;…

[code snippet] 生成隨機大文件

[code snippet] 生成隨機大文件 一個無聊的測試代碼&#xff0c;因為要測試大文件的網絡傳輸&#xff0c;就寫了一個隨機大文件生成腳本&#xff0c;做個備份。 基本上都是 GPT 生成的&#xff0c;哈哈。 C# 代碼 namespace ConsolePlayground;internal class BigFileGenera…

IOS17閃退問題Assertion failure in void _UIGraphicsBeginImageContextWithOptions

最近項目更新到最新版本IOS17&#xff0c;發現一個以前的頁面突然閃退了。原來是IOS17下&#xff0c;這個方法 UIGraphicsBeginImageContext(CGSize size) 已經被移除&#xff0c;原參數如果size為0的話&#xff0c;會出現閃退現象。 根據說明&#xff0c;上述方法已經被替換…

【shell腳本速成】python安裝腳本

文章目錄 案例需求應用場景解決問題腳本思路案例代碼 &#x1f308;你好呀&#xff01;我是 山頂風景獨好 &#x1f388;歡迎踏入我的博客世界&#xff0c;能與您在此邂逅&#xff0c;真是緣分使然&#xff01;&#x1f60a; &#x1f338;愿您在此停留的每一刻&#xff0c;都沐…

React 中 useEffect

React 中 useEffect 是副作用函數&#xff0c;副作用函數通常是處理外圍系統交互的邏輯。那么 useEffect 是怎處理的呢&#xff1f;React 組件都是純函數&#xff0c;需要將副作用的邏輯通過副作用函數抽離出去&#xff0c;也就是副作用函數是不影響函數組件的返回值的。例如&a…

vue中如何使用echarts和echarts-gl實現三維折線圖

一、vue中使用三維折線圖 效果圖&#xff1a; 二、使用步驟 1.引入庫 安裝echarts 在package.json文件中添加 "dependencies": {"echarts": "^5.1.2""echarts-gl": "^1.1.1",// "echarts-gl": "^2.0.8…

5G超寬,遠程診療帶來優質就醫體驗

上篇&#xff08;5G與4G的區別-CSDN博客&#xff09;講了4G與5G的區別&#xff0c;大家可以看到5G 具備高帶寬、低時延的特性&#xff0c;可以廣泛應用在各種物聯網場景下。 今天和大家簡單聊聊5G遠程診療。 遠程診療是一種利用信息通信技術為患者提供醫療服務的方式。它允許…