女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

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

    文章

    2984

    瀏覽量

    106798
  • 線程池
    +關注

    關注

    0

    文章

    57

    瀏覽量

    7078

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

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

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    Java應用OOM問題的排查過程

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

    Java 23功能介紹

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

    socket 多線程編程實現方法

    在現代網絡編程中,多線程技術被廣泛應用于提高服務器的并發處理能力。Socket編程是網絡通信的基礎,而將多線程技術應用于Socket編程,可以顯著提升服務器的性能。 多線程編程的基本概念 多
    的頭像 發表于 11-12 14:16 ?873次閱讀

    的無線測溫在線監測系統

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

    怎么在JAVA中確定線性大小

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

    Python中多線程和多進程的區別

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

    買藥秒送 JADE動態線程實踐及原理淺析

    一、背景及JADE介紹 買藥秒送是健康即時零售業務新的核心流量場域,面對京東首頁高流量曝光,我們對頻道頁整個技術架構方案進行升級,保障接口高性能、系統高可用。 動態線程是買藥頻道應用的技術之一
    的頭像 發表于 09-04 11:11 ?1090次閱讀
    買藥秒送 JADE動態<b class='flag-5'>線程</b><b class='flag-5'>池</b>實踐及原理淺析

    CPU線程和程序線程的區別

    CPU的線程與程序的線程在概念、作用、實現方式以及性能影響等方面存在顯著差異。以下是對兩者區別的詳細闡述,旨在深入探討這一技術話題。
    的頭像 發表于 09-02 11:18 ?1894次閱讀

    基于OpenHarmony標準系統的C++公共基礎類庫案例:ThreadPoll

    1、程序簡介 該程序是基于OpenHarmony標準系統的C++公共基礎類庫的線程處理:ThreadPoll。 本案例完成如下工作: 創建1個線程,設置該
    發表于 08-12 11:42

    華納云:java web和java有什么區別java web和java有什么區別

    Java Web和Java是兩個不同的概念,它們在功能、用途和實現方式上存在一些區別,下面將詳細介紹它們之間的區別。 1. 功能和用途: – Java是一種編程語言,它提供了一種用于開發各種應用程序
    的頭像 發表于 07-16 13:35 ?1340次閱讀
    華納云:<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區別<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區別

    卷積神經網絡中化層的作用

    。其中,化層(Pooling Layer)作為CNN的重要組成部分,在降低模型復雜度、提高計算效率以及增強模型的不變性和魯棒性方面發揮著關鍵作用。本文將從多個方面深入探討化層的作用,力求全面解析其在CNN中的核心地位。
    的頭像 發表于 07-03 15:58 ?3033次閱讀

    從多線程設計模式到對 CompletableFuture 的應用

    最近在開發 延保服務 頻道頁時,為了提高查詢效率,使用到了多線程技術。為了對多線程方案設計有更加充分的了解,在業余時間讀完了《圖解 Java線程設計模式》這本書,覺得收獲良多。本篇
    的頭像 發表于 06-26 14:18 ?600次閱讀
    從多<b class='flag-5'>線程</b>設計模式到對 CompletableFuture 的應用

    探索虛擬線程:原理與實現

    虛擬線程的引入與優勢 在Loom項目之前,Java虛擬機(JVM)中的線程是通過java.lang.Thread類型來實現的,這些線程被稱為
    的頭像 發表于 06-24 11:35 ?518次閱讀
    探索虛擬<b class='flag-5'>線程</b>:原理與實現

    鴻蒙開發:【線程模型】

    管理其他線程的ArkTS引擎實例,例如使用TaskPool(任務)創建任務或取消任務、啟動和終止Worker線程
    的頭像 發表于 06-13 16:38 ?652次閱讀
    鴻蒙開發:【<b class='flag-5'>線程</b>模型】

    動態線程思想學習及實踐

    相關文檔 美團線程實踐:https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html 線程
    的頭像 發表于 06-13 15:43 ?1442次閱讀
    動態<b class='flag-5'>線程</b><b class='flag-5'>池</b>思想學習及實踐