国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Java線程池核心原理

OSC開源社區 ? 來源:冰河技術 ? 2023-04-21 10:24 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

本文的整體結構如下所示。

f7ed04c8-df9c-11ed-bfe3-dac502259ad0.png

Java線程池核心原理

看過Java線程池源碼的小伙伴都知道,在Java線程池中最核心的類就是ThreadPoolExecutor,而在ThreadPoolExecutor類中最核心的構造方法就是帶有7個參數的構造方法,如下所示。

publicThreadPoolExecutor(intcorePoolSize,
intmaximumPoolSize,
longkeepAliveTime,
TimeUnitunit,
BlockingQueueworkQueue,
ThreadFactorythreadFactory,
RejectedExecutionHandlerhandler)

各參數的含義如下所示。

corePoolSize:線程池中的常駐核心線程數。

maximumPoolSize:線程池能夠容納同時執行的最大線程數,此值大于等于1。

keepAliveTime:多余的空閑線程存活時間,當空間時間達到keepAliveTime值時,多余的線程會被銷毀直到只剩下corePoolSize個線程為止。

unit:keepAliveTime的單位。

workQueue:任務隊列,被提交但尚未被執行的任務。

threadFactory:表示生成線程池中工作線程的線程工廠,用戶創建新線程,一般用默認即可。

handler:拒絕策略,表示當線程隊列滿了并且工作線程大于等于線程池的最大顯示數(maxnumPoolSize)時,如何來拒絕請求執行的runnable的策略。

并且Java的線程池是通過 生產者-消費者模式 實現的,線程池的使用方是生產者,而線程池本身就是消費者。

Java線程池的核心工作流程如下圖所示。

f8050b90-df9c-11ed-bfe3-dac502259ad0.png

手擼Java線程池

我們自己手動實現的線程池要比Java自身的線程池簡單的多,我們去掉了各種復雜的處理方式,只保留了最核心的原理:線程池的使用者向任務隊列中添加任務,而線程池本身從任務隊列中消費任務并執行任務。

f812d59a-df9c-11ed-bfe3-dac502259ad0.png

只要理解了這個核心原理,接下來的代碼就簡單多了。在實現這個簡單的線程池時,我們可以將整個實現過程進行拆解。拆解后的實現流程為:定義核心字段、創建內部類WorkThread、創建ThreadPool類的構造方法和創建執行任務的方法。

f81fd010-df9c-11ed-bfe3-dac502259ad0.png

定義核心字段

首先,我們創建一個名稱為ThreadPool的Java類,并在這個類中定義如下核心字段。

DEFAULT_WORKQUEUE_SIZE:靜態常量,表示默認的阻塞隊列大小。

workQueue:模擬實際的線程池使用阻塞隊列來實現生產者-消費者模式。

workThreads:模擬實際的線程池使用List集合保存線程池內部的工作線程。

核心代碼如下所示。

//默認阻塞隊列大小
privatestaticfinalintDEFAULT_WORKQUEUE_SIZE=5;

//模擬實際的線程池使用阻塞隊列來實現生產者-消費者模式
privateBlockingQueueworkQueue;

//模擬實際的線程池使用List集合保存線程池內部的工作線程
privateListworkThreads=newArrayList();

創建內部類WordThread

在ThreadPool類中創建一個內部類WorkThread,模擬線程池中的工作線程。主要的作用就是消費workQueue中的任務,并執行任務。由于工作線程需要不斷從workQueue中獲取任務,所以,這里使用了while(true)循環不斷嘗試消費隊列中的任務。

核心代碼如下所示。

//內部類WorkThread,模擬線程池中的工作線程
//主要的作用就是消費workQueue中的任務,并執行
//由于工作線程需要不斷從workQueue中獲取任務,使用了while(true)循環不斷嘗試消費隊列中的任務
classWorkThreadextendsThread{
@Override
publicvoidrun(){
//不斷循環獲取隊列中的任務
while(true){
//當沒有任務時,會阻塞
try{
RunnableworkTask=workQueue.take();
workTask.run();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}

創建ThreadPool類的構造方法

這里,我們為ThreadPool類創建兩個構造方法,一個構造方法中傳入線程池的容量大小和阻塞隊列,另一個構造方法中只傳入線程池的容量大小。

核心代碼如下所示。

//在ThreadPool的構造方法中傳入線程池的大小和阻塞隊列
publicThreadPool(intpoolSize,BlockingQueueworkQueue){
this.workQueue=workQueue;
//創建poolSize個工作線程并將其加入到workThreads集合中
IntStream.range(0,poolSize).forEach((i)->{
WorkThreadworkThread=newWorkThread();
workThread.start();
workThreads.add(workThread);
});
}

//在ThreadPool的構造方法中傳入線程池的大小
publicThreadPool(intpoolSize){
this(poolSize,newLinkedBlockingQueue<>(DEFAULT_WORKQUEUE_SIZE));
}

創建執行任務的方法

在ThreadPool類中創建執行任務的方法execute(),execute()方法的實現比較簡單,就是將方法接收到的Runnable任務加入到workQueue隊列中。

核心代碼如下所示。

//通過線程池執行任務
publicvoidexecute(Runnabletask){
try{
workQueue.put(task);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}

完整源碼

這里,我們給出手動實現的ThreadPool線程池的完整源代碼,如下所示。

packageio.binghe.thread.pool;

importjava.util.ArrayList;
importjava.util.List;
importjava.util.concurrent.BlockingQueue;
importjava.util.concurrent.LinkedBlockingQueue;
importjava.util.stream.IntStream;

/**
*@authorbinghe
*@version1.0.0
*@description自定義線程池
*/
publicclassThreadPool{

//默認阻塞隊列大小
privatestaticfinalintDEFAULT_WORKQUEUE_SIZE=5;

//模擬實際的線程池使用阻塞隊列來實現生產者-消費者模式
privateBlockingQueueworkQueue;

//模擬實際的線程池使用List集合保存線程池內部的工作線程
privateListworkThreads=newArrayList();

//在ThreadPool的構造方法中傳入線程池的大小和阻塞隊列
publicThreadPool(intpoolSize,BlockingQueueworkQueue){
this.workQueue=workQueue;
//創建poolSize個工作線程并將其加入到workThreads集合中
IntStream.range(0,poolSize).forEach((i)->{
WorkThreadworkThread=newWorkThread();
workThread.start();
workThreads.add(workThread);
});
}

//在ThreadPool的構造方法中傳入線程池的大小
publicThreadPool(intpoolSize){
this(poolSize,newLinkedBlockingQueue<>(DEFAULT_WORKQUEUE_SIZE));
}

//通過線程池執行任務
publicvoidexecute(Runnabletask){
try{
workQueue.put(task);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}

//內部類WorkThread,模擬線程池中的工作線程
//主要的作用就是消費workQueue中的任務,并執行
//由于工作線程需要不斷從workQueue中獲取任務,使用了while(true)循環不斷嘗試消費隊列中的任務
classWorkThreadextendsThread{
@Override
publicvoidrun(){
//不斷循環獲取隊列中的任務
while(true){
//當沒有任務時,會阻塞
try{
RunnableworkTask=workQueue.take();
workTask.run();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
}

沒錯,我們僅僅用了幾十行Java代碼就實現了一個極簡版的Java線程池,沒錯,這個極簡版的Java線程池的代碼卻體現了Java線程池的核心原理。

接下來,我們測試下這個極簡版的Java線程池。

編寫測試程序

測試程序也比較簡單,就是通過在main()方法中調用ThreadPool類的構造方法,傳入線程池的大小,創建一個ThreadPool類的實例,然后循環10次調用ThreadPool類的execute()方法,向線程池中提交的任務為:打印當前線程的名稱--->> Hello ThreadPool。

整體測試代碼如下所示。

packageio.binghe.thread.pool.test;

importio.binghe.thread.pool.ThreadPool;

importjava.util.stream.IntStream;

/**
*@authorbinghe
*@version1.0.0
*@description測試自定義線程池
*/
publicclassThreadPoolTest{

publicstaticvoidmain(String[]args){
ThreadPoolthreadPool=newThreadPool(10);
IntStream.range(0,10).forEach((i)->{
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+"--->>HelloThreadPool");
});
});
}
}

接下來,運行ThreadPoolTest類的main()方法,會輸出如下信息。

Thread-0--->>HelloThreadPool
Thread-9--->>HelloThreadPool
Thread-5--->>HelloThreadPool
Thread-8--->>HelloThreadPool
Thread-4--->>HelloThreadPool
Thread-1--->>HelloThreadPool
Thread-2--->>HelloThreadPool
Thread-5--->>HelloThreadPool
Thread-9--->>HelloThreadPool
Thread-0--->>HelloThreadPool

至此,我們自定義的Java線程池就開發完成了。

總結

線程池的核心原理其實并不復雜,只要我們耐心的分析,深入其源碼理解線程池的核心本質,你就會發現線程池的設計原來是如此的優雅。希望通過這個手寫線程池的小例子,能夠讓你更好的理解線程池的核心原理。





審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    20

    文章

    3001

    瀏覽量

    116422
  • 線程池
    +關注

    關注

    0

    文章

    58

    瀏覽量

    7388

原文標題:10分鐘帶你徒手做個Java線程池

文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    全棧國產AI Coding上線:摩爾線程+硅基流動+智譜,強強聯合!

    摩爾線程今日正式推出AI Coding Plan 智能編程服務。作為首個基于國產全功能 GPU 算力底座構建的智能開發解決方案,該服務以 MTT S5000 強勁的全精度計算能力為核心驅動,融合硅
    的頭像 發表于 02-03 17:07 ?1441次閱讀
    全棧國產AI Coding上線:摩爾<b class='flag-5'>線程</b>+硅基流動+智譜,強強聯合!

    解析Linux的進程、線程和協程

    和系統資源。線程的引入使得多核處理器得以充分利用,因為多線程程序可以更有效地分配和管理多核心的計算資源。 線程的特點包括: (1)共享性:線程
    發表于 12-22 11:00

    開放協作,共筑生態——思爾芯參與上海開放處理器產業創新中心開業儀式暨RISC-V專利聯盟專利儀式

    在推動芯片產業自主創新、構建開放協作生態的背景下,上海開放處理器產業創新中心(SOPIC)于2025年12月12日在上海張江正式舉辦開業儀式。同期舉行的RISC-V專利儀式上,思爾芯作為首批入
    的頭像 發表于 12-15 17:38 ?1149次閱讀
    開放協作,共筑生態——思爾芯參與上海開放處理器產業創新中心開業儀式暨RISC-V專利聯盟專利<b class='flag-5'>池</b>入<b class='flag-5'>池</b>儀式

    C語言內存使用

    ,整個堆有可能被弄得支離破碎,最終導致大量內存浪費。 那么這種情況下,我們解決這類問題的思路,就是創建一個內存。 內存,實際上就是我們讓程序創建出來的一塊額外的緩存區域,如果有需要釋放內存,先
    發表于 12-11 07:57

    線程的系統

    線程系統的事件響應也是在中斷中完成的,但事件的處理是在線程中完成的。在多線程系統中,線程跟中斷一樣,也具有優先級,優先級高的線程會被優先執
    發表于 12-08 07:55

    Linux多線程對比單線程的優勢

    在Linux系統中,線程是操作系統能夠進行運算調度的最小單位。線程被包含在進程之中,是進程中的實際運行單位。一個進程可以擁有多個線程,這些線程共享相同的內存空間和系統資源。
    發表于 12-01 06:11

    Arm Neoverse CPU上大代碼量Java應用的性能測試

    Java 是互聯網領域廣泛使用的編程語言。Java 應用的一些特性使其性能表現與提前編譯的原生應用(例如 C 程序)大相徑庭。由于 Java 字節碼無法直接在 CPU 上執行,因此通常運行時在
    的頭像 發表于 11-05 11:25 ?752次閱讀
    Arm Neoverse CPU上大代碼量<b class='flag-5'>Java</b>應用的性能測試

    數據全復用高性能化層設計思路分享

    大家好,本團隊此次分享的內容為可實現數據全復用高性能化層設計思路,核心部分主要由以下3個部分組成; 1.SRAM讀取模塊;——化使用的存儲為SRAM 基于SRAM讀與寫時序,約束
    發表于 10-29 07:10

    沉砂物聯網監控管理系統方案

    沉砂作為污水處理工藝中的核心預處理單元,承擔著去除污水中砂粒、礫石等重型顆粒物的關鍵任務。其運行效率直接影響后續處理設備的壽命與整體處理效果。隨著環保政策趨嚴與污水處理規模擴大,傳統人工巡檢模式已
    的頭像 發表于 10-14 14:08 ?410次閱讀
    沉砂<b class='flag-5'>池</b>物聯網監控管理系統方案

    Java效率提升指南:5個Java工具選型建議及Perforce JRebel和XRebel介紹

    企業級Java環境越來越復雜,真正的破局點,可能不在“人”,而在于“工具”。5個實用建議,幫你理清Java工具的選型思路。
    的頭像 發表于 09-11 13:59 ?1479次閱讀
    <b class='flag-5'>Java</b>效率提升指南:5個<b class='flag-5'>Java</b>工具選型建議及Perforce JRebel和XRebel介紹

    Task任務:LuatOS實現“任務級并發”的核心引擎

    Task任務通過其強大的并發處理能力,使LuatOS能夠在單線程環境中模擬多線程執行,通過協程的掛起與恢復機制,實現任務級的并行操作,顯著提升系統效能。 sys核心庫是LuatOS運行框架庫,也是
    的頭像 發表于 08-28 13:49 ?508次閱讀
    Task任務:LuatOS實現“任務級并發”的<b class='flag-5'>核心</b>引擎

    摩爾線程“AI工廠”:五大核心技術支撐,打造大模型訓練超級工廠

    2025年7月25日,上海——在世界人工智能大會(WAIC 2025)開幕前夕,摩爾線程以“算力進化,精度革命”為主題舉辦技術分享會,并創新性提出“AI工廠”理念。摩爾線程創始人兼CEO張建中在主題
    的頭像 發表于 07-28 11:28 ?4538次閱讀
    摩爾<b class='flag-5'>線程</b>“AI工廠”:五大<b class='flag-5'>核心</b>技術支撐,打造大模型訓練超級工廠

    線程的安全注意事項

    線程安全是指多個線程同時訪問或修改共享資源時,能夠保證程序的正確性和可靠性。 開發者選擇TaskPool或Worker進行多線程開發時,在TaskPool和Worker的工作線程中導
    發表于 06-20 07:49

    鴻蒙5開發寶藏案例分享---應用并發設計

    線程 --> |系統托管| FFRT_I/O[FFRT I/O線程] 三大核心理念 : 內存隔離 :
    發表于 06-12 16:19

    Java開發者必備的效率工具——Perforce JRebel是什么?為什么很多Java開發者在用?

    Perforce JRebel是一款Java開發效率工具,旨在幫助java開發人員更快地編寫更好的應用程序。JRebel可即時重新加載對代碼的修改,無需重啟或重新部署應用程序,就能讓開發者即時看到代碼更改的效果,從而縮短開發、調試和測試周期,大大提升開發效率。
    的頭像 發表于 04-27 13:44 ?844次閱讀
    <b class='flag-5'>Java</b>開發者必備的效率工具——Perforce JRebel是什么?為什么很多<b class='flag-5'>Java</b>開發者在用?