那曲檬骨新材料有限公司

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

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

3天內不再提示

Java中的線程池包括哪些

科技綠洲 ? 來源:Java技術指北 ? 作者:Java技術指北 ? 2023-10-11 15:33 ? 次閱讀

線程池是用來統一管理線程的,在 Java 中創建和銷毀線程都是一件消耗資源的事情,線程池可以重復使用線程,不再頻繁的創建、銷毀線程。

初識

Java 中的線程池是由 juc 即 java.util.concurrent 包來實現的,最主要的就是 ThreadPoolExecutor 類。

圖片

  1. Executor: 代表線程池的接口,有一個 execute() 方法,給一個 Runnable 類型對象就可以分配一個線程執行。
  2. ExecutorService:是 Executor 的子接口,提供了線程池的一些生命周期方法。代表了一個線程池管理器。
  3. ThreadPoolExecutor:一個線程池的實現類,可以通過調用 Executors 靜態工廠方法來創建線程池并返回一個 ExecutorService 對象。

ThredadPoolExcutor

看一下最常用的 ThredadPoolExcutor ,下圖是 ThreadPoolExecutor 的構造函數

圖片

從源碼中可以看出每個前三個構造函數都調用了最后一個構造函數。

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue< Runnable > workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
    //省略代碼
    }

仔細分析一下構造參數

  1. corePoolSize:線程池里的核心線程數量,當正在運行的線程數量小于核心線程數量,就創建一個核心線程。
  2. maximumPoolSize:線程池最多能放多少個線程。
  3. keepAliveTime:線程的閑置時間,當線程池里面的線程數量大于 corePoolSize 的時候,多出來的線程在等待的時間之后會被釋放掉
  4. unit:keepAliveTime 的單位
  5. workQueue:一個阻塞隊列。
  6. threadFactory:通過這個工廠模式創建線程。
  7. handler:處理線程隊列滿了報錯的。

結合線程池的參數簡單的畫出線程池的工作模型。

圖片

當線程池中的核心線程數量 corePoolSize 滿了,就會將任務先加入到任務隊列 workQueue 中。

執行過程

線程池的執行過程如下圖:

  1. 首先判斷核心線程 corePoolSize 是不是滿了,如果沒有滿,就執行任務,否則就進入下一步。
  2. 線程池判斷任務隊列 workQueue 是否了,如果沒有滿,則將新提交的任務放入在這個任務隊列里。如果任務隊列滿了,則進入一步。
  3. 判斷線程池里的線程達到了最大線程數 maximumPoolSize,如果沒有,則創建一個新的線程來執行任務。如果已經滿了,則交給拒絕策略來處理這個任務。

圖片

常用的線程池

線程池的創建需要有 7 個參數,還是比較復雜的,JVM 為我們提供了 Executors 類中多個靜態工廠,生成一些常用的線程池。

SingleThreadExecutor

單線程的線程池,里面就一個核心線程數。

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue< Runnable >()));
}

ThreadPoolExecutor 參數只有一個核心線程數和一個最大線程數,這個很少用到。它保證了所有線程的執行順序都是按照提交到線程池的順序執行。

public class TodoDemo implements Runnable {


    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        for(int i = 0; i < 10; i++) {
            executorService.execute(new TodoDemo());
        }
        executorService.shutdown();
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " Running");
    }
}

只有一個線程在跑。

圖片

FixedThreadExecutor

固定數量的線程池

return new ThreadPoolExecutor(nThreads, nThreads,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue< Runnable >());
}

這個線程池的特點就是線程的數量是固定的,超過這個數量的任務就得在 LinkedBlockingQueue 中排隊等候。

public class TodoDemo implements Runnable {
    
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        for(int i = 0; i < 10; i++) {
            executorService.execute(new TodoDemo());
        }
        executorService.shutdown();
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " Running");
    }
}

可以看到就算提交 100 個任務也只有 3 個線程。

圖片

CachedThreadExecutor

自動回收空閑的線程

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                    60L, TimeUnit.SECONDS,
                                    new SynchronousQueue< Runnable >());
}

可以看到核心線程數量為 0, 表示不會永久保留任何的線程,最大線程的數量是 Integer.MAX_VALUE,可以無限制的創建線程,但是當有大量線程處于空閑狀態的時候,超過 60s 就會被銷毀。

public class TodoDemo implements Runnable {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for(int i = 0; i < 20; i++) {
            executorService.execute(new TodoDemo());
        }
        executorService.shutdown();
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " Running");
    }
}

雖然這個線程池可以想建多少個線程就建多少個線程,但是還是會重用已經完成任務的線程。

圖片

一般最常用的是FixedThreadExecutor和CachedThreadExecutor。

線程池的回收策略

在線程池中任務隊列已經滿了,并且線程的數量已經到了最大的數量,這個時候再加任務線程池就不再接受了。

在 ThreadPoolExecutor 里有 4 種拒絕策略,都實現了 RejectedExecutionHandler:

  1. AbortPolicy 表示拋出一個異常。
  2. DiscardPolicy 拒絕任務但是不提示。
  3. DiscardOldestPolicy 丟棄掉老的任務,執行新的任務。
  4. CallerRunsPolicy 直接調用線程處理。

總結

線程池的作用是提高系統的性能和線程的利用率,不再需要頻繁的創建和銷毀線程。如果使用最簡單的方式創建線程,在用戶量巨大的情況下,消耗的性能是非常恐怖的,所以才有了線程池。

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

    關注

    33

    文章

    8691

    瀏覽量

    151911
  • JAVA
    +關注

    關注

    19

    文章

    2974

    瀏覽量

    105136
  • 管理器
    +關注

    關注

    0

    文章

    248

    瀏覽量

    18613
  • 函數
    +關注

    關注

    3

    文章

    4346

    瀏覽量

    62968
  • 線程池
    +關注

    關注

    0

    文章

    57

    瀏覽量

    6893
收藏 人收藏

    評論

    相關推薦

    Java線程的用法

    本文將介紹一下Java線程的用法。 基礎介紹 什么是多線程 指的是在一個進程同時運行多個線程,每個
    的頭像 發表于 09-30 17:07 ?1004次閱讀

    動態線程思想學習及實踐

    ://www.javadoop.com/post/java-thread-pool? 引言 在后臺項目開發過程,我們常常借助線程來實現多線程
    的頭像 發表于 06-13 15:43 ?1245次閱讀
    動態<b class='flag-5'>線程</b><b class='flag-5'>池</b>思想學習及實踐

    線程是如何實現的

    線程的概念是什么?線程是如何實現的?
    發表于 02-28 06:20

    java自帶的線程方法

    二、原理分析 從上面使用線程的例子來看,最主要就是兩步,構造ThreadPoolExecutor對象,然后每來一個任務,就調用ThreadPoolExecutor對象的execute方法。 1
    發表于 09-27 11:06 ?0次下載

    如何正確關閉線程

    /huajiexiewenfeng/java-concurrent 本章模塊:threadpool 1.線程示例 public class ShutDownThreadPoolDemo { private
    的頭像 發表于 09-29 14:41 ?9999次閱讀

    線程線程

    線程通常用于服務器應用程序。 每個傳入請求都將分配給線程池中的一個線程,因此可以異步處理請求,而不會占用主線程,也不會延遲后續請求的處理
    的頭像 發表于 02-28 09:53 ?832次閱讀
    多<b class='flag-5'>線程</b>之<b class='flag-5'>線程</b><b class='flag-5'>池</b>

    Java線程核心原理

    看過Java線程源碼的小伙伴都知道,在Java線程池中最核心的類就是ThreadPoolExecutor,
    的頭像 發表于 04-21 10:24 ?908次閱讀

    Spring 的線程應用

    我們在日常開發,經常跟多線程打交道,Spring 為我們提供了一個線程方便我們開發,它就是 ThreadPoolTaskExecutor ,接下來我們就來聊聊 Spring 的
    的頭像 發表于 10-13 10:47 ?650次閱讀
    Spring 的<b class='flag-5'>線程</b><b class='flag-5'>池</b>應用

    如何設計一個線程JAVA線程是如何設計的?

    線程(thread)是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程的實際 運作單位。
    的頭像 發表于 11-07 09:12 ?1752次閱讀
    如何設計一個<b class='flag-5'>線程</b><b class='flag-5'>池</b>?<b class='flag-5'>JAVA</b><b class='flag-5'>中</b>的<b class='flag-5'>線程</b><b class='flag-5'>池</b>是如何設計的?

    線程基本概念與原理

    一、線程基本概念與原理 1.1 線程概念及優勢 C++線程簡介
    的頭像 發表于 11-10 10:24 ?578次閱讀

    線程的基本概念

    ? 呃呃,我這么問就很奇怪,因為線程是什么我都沒說,怎么會知道為什么會有線程呢?所以我打算帶大家去思考一個場景: 當我們的程序:有一批
    的頭像 發表于 11-10 16:37 ?560次閱讀
    <b class='flag-5'>線程</b><b class='flag-5'>池</b>的基本概念

    線程的運轉流程圖 化技術實踐案例解析

    作為一名Java開發人員,化技術或多或少在業務代碼中使用。常見的包括線程、連接等。也是因為
    的頭像 發表于 11-24 10:22 ?514次閱讀
    <b class='flag-5'>線程</b><b class='flag-5'>池</b>的運轉流程圖 <b class='flag-5'>池</b>化技術實踐案例解析

    線程的創建方式有幾種

    線程是一種用于管理和調度線程的技術,能夠有效地提高系統的性能和資源利用率。它通過預先創建一組線程并維護一個工作隊列,將任務提交給線程
    的頭像 發表于 12-04 16:52 ?933次閱讀

    什么是動態線程?動態線程的簡單實現思路

    因此,動態可監控線程一種針對以上痛點開發的線程管理工具。主要可實現功能有:提供對 Spring 應用內線程
    的頭像 發表于 02-28 10:42 ?721次閱讀

    java實現多線程的幾種方式

    了多種實現多線程的方式,本文將詳細介紹以下幾種方式: 1.繼承Thread類 2.實現Runnable接口 3.Callable和Future 4.線程 5.Java 8
    的頭像 發表于 03-14 16:55 ?781次閱讀
    缅甸百家乐龙虎斗| 娱乐城注册| 百家乐娱乐天上人间| 百家乐官网视频双扣下载| 大发娱乐城开户| 百家乐玩法官网| 百家乐赌机玩法| 真人百家乐平台下载| 澳门百家乐官网论谈| zaixian百家乐| 棋牌游戏网| 娱乐城首存| 澳门在线转盘| 百家乐打法| 新利网上娱乐| bet9全讯网查询| 六合彩150期| 君豪棋牌怎么样| bet365合法吗| 大赢家| 娱乐百家乐的玩法技巧和规则 | 百家乐如何看| 百家乐如何赚钱洗码| 华泰百家乐的玩法技巧和规则| 海港城百家乐的玩法技巧和规则 | 百家乐官网规律打法| 金城百家乐官网买卖路| 百家乐官网的最佳玩| 百家乐官网永利赌场娱乐网规则| 玩百家乐官网必赢的心法| 百家乐官网网上真钱娱乐场开户注册| 淘金百家乐官网的玩法技巧和规则| 网络百家乐官网破| 百家乐代理商博彩e族| 新奥博百家乐娱乐城| 大佬百家乐的玩法技巧和规则| 水果机价格| 大发888下载| 波音网址| 百家乐官网娱乐城主页| 百家乐官网有诈吗|