18video性欧美19sex,欧美高清videosddfsexhd,性少妇videosexfreexxx片中国,激情五月激情综合五月看花,亚洲人成网77777色在线播放

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

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

3天內(nèi)不再提示

Java線程池核心原理

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

掃碼添加小助手

加入工程師交流群

本文的整體結(jié)構(gòu)如下所示。

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

Java線程池核心原理

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

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

各參數(shù)的含義如下所示。

corePoolSize:線程池中的常駐核心線程數(shù)。

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

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

unit:keepAliveTime的單位。

workQueue:任務(wù)隊列,被提交但尚未被執(zhí)行的任務(wù)。

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

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

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

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

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

手擼Java線程池

我們自己手動實現(xiàn)的線程池要比Java自身的線程池簡單的多,我們?nèi)サ袅烁鞣N復(fù)雜的處理方式,只保留了最核心的原理:線程池的使用者向任務(wù)隊列中添加任務(wù),而線程池本身從任務(wù)隊列中消費任務(wù)并執(zhí)行任務(wù)。

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

只要理解了這個核心原理,接下來的代碼就簡單多了。在實現(xiàn)這個簡單的線程池時,我們可以將整個實現(xiàn)過程進行拆解。拆解后的實現(xiàn)流程為:定義核心字段、創(chuàng)建內(nèi)部類WorkThread、創(chuàng)建ThreadPool類的構(gòu)造方法和創(chuàng)建執(zhí)行任務(wù)的方法。

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

定義核心字段

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

DEFAULT_WORKQUEUE_SIZE:靜態(tài)常量,表示默認的阻塞隊列大小。

workQueue:模擬實際的線程池使用阻塞隊列來實現(xiàn)生產(chǎn)者-消費者模式。

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

核心代碼如下所示。

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

//模擬實際的線程池使用阻塞隊列來實現(xiàn)生產(chǎn)者-消費者模式
privateBlockingQueueworkQueue;

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

創(chuàng)建內(nèi)部類WordThread

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

核心代碼如下所示。

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

創(chuàng)建ThreadPool類的構(gòu)造方法

這里,我們?yōu)門hreadPool類創(chuàng)建兩個構(gòu)造方法,一個構(gòu)造方法中傳入線程池的容量大小和阻塞隊列,另一個構(gòu)造方法中只傳入線程池的容量大小。

核心代碼如下所示。

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

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

創(chuàng)建執(zhí)行任務(wù)的方法

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

核心代碼如下所示。

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

完整源碼

這里,我們給出手動實現(xiàn)的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;

//模擬實際的線程池使用阻塞隊列來實現(xiàn)生產(chǎn)者-消費者模式
privateBlockingQueueworkQueue;

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

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

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

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

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

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

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

編寫測試程序

測試程序也比較簡單,就是通過在main()方法中調(diào)用ThreadPool類的構(gòu)造方法,傳入線程池的大小,創(chuàng)建一個ThreadPool類的實例,然后循環(huán)10次調(diào)用ThreadPool類的execute()方法,向線程池中提交的任務(wù)為:打印當前線程的名稱--->> 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線程池就開發(fā)完成了。

總結(jié)

線程池的核心原理其實并不復(fù)雜,只要我們耐心的分析,深入其源碼理解線程池的核心本質(zhì),你就會發(fā)現(xiàn)線程池的設(shè)計原來是如此的優(yōu)雅。希望通過這個手寫線程池的小例子,能夠讓你更好的理解線程池的核心原理。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    2992

    瀏覽量

    115064
  • 線程池
    +關(guān)注

    關(guān)注

    0

    文章

    57

    瀏覽量

    7276

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

文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

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

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

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

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

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

    2025年7月25日,上?!谑澜缛斯ぶ悄艽髸╓AIC 2025)開幕前夕,摩爾線程以“算力進化,精度革命”為主題舉辦技術(shù)分享會,并創(chuàng)新性提出“AI工廠”理念。摩爾線程創(chuàng)始人兼CEO張建中在主題
    的頭像 發(fā)表于 07-28 11:28 ?3666次閱讀
    摩爾<b class='flag-5'>線程</b>“AI工廠”:五大<b class='flag-5'>核心</b>技術(shù)支撐,打造大模型訓(xùn)練超級工廠

    鴻蒙5開發(fā)寶藏案例分享---應(yīng)用并發(fā)設(shè)計

    線程 --> |系統(tǒng)托管| FFRT_I/O[FFRT I/O線程] 三大核心理念 : 內(nèi)存隔離 :
    發(fā)表于 06-12 16:19

    Java應(yīng)用OOM問題的排查過程

    集團,大多數(shù)情況下Java堆的大小會設(shè)置為容器規(guī)格的50%~70%,但如果你設(shè)置為50%時還是遇到了OS OOM的問題,會不會無法忍受進而想要知道這是為什么?沒錯,我也有一樣的好奇。 背景 某核心應(yīng)用的負責(zé)同學(xué)反饋應(yīng)用存在少量機器OOM被OS kill的問題??磗unfi
    的頭像 發(fā)表于 02-12 11:15 ?958次閱讀
    <b class='flag-5'>Java</b>應(yīng)用OOM問題的排查過程

    基于OpenHarmony標準系統(tǒng)的C++公共基礎(chǔ)類庫案例:ThreadPoll

    1、程序簡介該程序是基于OpenHarmony標準系統(tǒng)的C++公共基礎(chǔ)類庫的線程處理:ThreadPoll。本案例完成如下工作:創(chuàng)建1個線程,設(shè)置該
    的頭像 發(fā)表于 02-10 18:09 ?522次閱讀
    基于OpenHarmony標準系統(tǒng)的C++公共基礎(chǔ)類庫案例:ThreadPoll

    SSM框架在Java開發(fā)中的應(yīng)用 如何使用SSM進行web開發(fā)

    SSM框架,即Spring、SpringMVC和MyBatis的整合,是Java Web開發(fā)中常用的技術(shù)棧。它通過分層架構(gòu),實現(xiàn)了視圖、控制、業(yè)務(wù)邏輯和數(shù)據(jù)訪問的分離,提高了代碼的可維護性和可擴展性
    的頭像 發(fā)表于 12-16 17:28 ?1975次閱讀

    Java 23功能介紹

    Java 23 包含全新和更新的 Java 語言功能、核心 API 以及 JVM,同時適合新的 Java 開發(fā)者和高級開發(fā)者。從?IntelliJ IDEA 2024.2?開始已支持
    的頭像 發(fā)表于 12-04 10:02 ?1341次閱讀
    <b class='flag-5'>Java</b> 23功能介紹

    Java集合API的改進介紹

    解答這些問題。 我們將逐步學(xué)習(xí) Java 集合類的優(yōu)化過程,并按版本逐一對比分析。主要討論的焦點將包括 JDK 1.0、1.2、1.4、1.5、1.6、1.8、9、10、11 和 21 版本的 Java 集合功能 Java 集合
    的頭像 發(fā)表于 11-22 11:12 ?782次閱讀
    <b class='flag-5'>Java</b>集合API的改進介紹

    深入探索:海外IP代理的安全性與管理

    海外IP代理的安全性與管理是使用這一工具時不可忽視的重要方面。
    的頭像 發(fā)表于 11-14 07:39 ?682次閱讀

    構(gòu)建便捷海外IP代理:策略與實踐

    構(gòu)建便捷海外IP代理是一個涉及多方面策略與實踐的過程。
    的頭像 發(fā)表于 11-14 07:34 ?730次閱讀

    socket 多線程編程實現(xiàn)方法

    在現(xiàn)代網(wǎng)絡(luò)編程中,多線程技術(shù)被廣泛應(yīng)用于提高服務(wù)器的并發(fā)處理能力。Socket編程是網(wǎng)絡(luò)通信的基礎(chǔ),而將多線程技術(shù)應(yīng)用于Socket編程,可以顯著提升服務(wù)器的性能。 多線程編程的基本概念 多
    的頭像 發(fā)表于 11-12 14:16 ?1358次閱讀

    Java中時間戳的使用

    Java中時間戳的使用
    的頭像 發(fā)表于 11-06 16:04 ?673次閱讀
    <b class='flag-5'>Java</b>中時間戳的使用

    的無線測溫在線監(jiān)測系統(tǒng)

    今天分享的酒廠窖的無線測溫系統(tǒng),包含硬件和軟件為一體的標準解決方案。 行業(yè)背景 說到窖的測溫,不得不從酒廠的酒廠的發(fā)酵說起。酒廠發(fā)酵是指用于生產(chǎn)釀酒的一種設(shè)備,通常由不銹鋼或玻
    的頭像 發(fā)表于 10-28 09:52 ?588次閱讀
    窖<b class='flag-5'>池</b>的無線測溫在線監(jiān)測系統(tǒng)

    怎么在JAVA中確定線性大小

    JAVA中確定線性大小,分別介紹CPU密集型任務(wù)和I/O密集型任務(wù)及其處理方法。
    的頭像 發(fā)表于 10-24 14:02 ?662次閱讀

    Python中多線程和多進程的區(qū)別

    Python作為一種高級編程語言,提供了多種并發(fā)編程的方式,其中多線程與多進程是最常見的兩種方式之一。在本文中,我們將探討Python中多線程與多進程的概念、區(qū)別以及如何使用線程與進
    的頭像 發(fā)表于 10-23 11:48 ?1261次閱讀
    Python中多<b class='flag-5'>線程</b>和多進程的區(qū)別