欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談Java ThreadPoolExecutor的使用

 更新時(shí)間:2021年05月14日 15:34:30   作者:春刀c  
今天我們來學(xué)習(xí)一下Java ThreadPoolExecutor的使用,文中有非常詳細(xì)的介紹及代碼示例,對正在學(xué)習(xí)Java的小伙伴們有很大的幫助,需要的朋友可以參考下

一、前言

線程池主要由以下4個(gè)核心組件組成。

  • 線程池管理器:用于創(chuàng)建并管理線程池
  • 工作線程:線程池中執(zhí)行具體任務(wù)的線程
  • 任務(wù)接口:用于定義工作線程的調(diào)度和執(zhí)行策略,只有線程實(shí)現(xiàn)了該接口,線程中的任務(wù)才能被線程池調(diào)度
  • 任務(wù)隊(duì)列:放待處理的任務(wù),新的任務(wù)將會(huì)不斷被加入隊(duì)列中,執(zhí)行完成的任務(wù)將從隊(duì)列中移除

在這里插入圖片描述

二、ThreadPoolExecutor

如下是線程池的構(gòu)造方法

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
}

其中具體參數(shù)含義為:

1.corePoolSize:線程池中核心線程的數(shù)量

2.maximumPoolSize:線程池中最大線程的數(shù)量

3.keepAliveTime:當(dāng)線程數(shù)量超過corePoolSize時(shí),空閑線程的存活時(shí)間

4.unit:keepAliveTime的時(shí)間單位

5.workQueue:任務(wù)隊(duì)列,被提交但尚未被執(zhí)行的任務(wù)存放的地方

6.threadFactory:線程工廠,用于創(chuàng)建線程,可使用默認(rèn)的線程工廠或自定義線程工廠

7.handler:由于任務(wù)過多或其他原因?qū)е戮€程池?zé)o法處理時(shí)的任務(wù)拒絕策略

三、構(gòu)造函數(shù)參數(shù)解析

編寫測試類如下:

public class ThreadPoolSerialTest {
    public static void main(String[] args) {
        //核心線程數(shù)
        int corePoolSize = 2;
        //最大線程數(shù)
        int maximumPoolSize = 4;
        //超過corePoolSize線程數(shù)量的線程最大空閑時(shí)間
        long keepAliveTime = 2;
        //以秒為時(shí)間單位
        TimeUnit unit = TimeUnit.SECONDS;
        //創(chuàng)建工作隊(duì)列,用于存放提交的等待執(zhí)行任務(wù)
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
        ThreadPoolExecutor threadPoolExecutor = null;

        try {
            // 1.創(chuàng)建線程池
            threadPoolExecutor = new ThreadPoolExecutor(corePoolSize,
                    maximumPoolSize,
                    keepAliveTime,
                    unit,
                    workQueue,
                    new ThreadPoolExecutor.AbortPolicy());
            // 2.循環(huán)提交任務(wù)
            for (int i = 0; i < 6; i++) {
                //提交任務(wù)的索引
                final int index = (i+1);
                threadPoolExecutor.submit(()->{
                    //線程打印輸出
                    System.out.println("大家好,我是線程:"+index);
                    try {
                        //模擬線程執(zhí)行時(shí)間,10s
                        Thread.sleep(10000);
                        System.out.println("線程:"+index+"運(yùn)行完畢");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
                //每個(gè)任務(wù)提交后休眠500ms再提交下一個(gè)任務(wù),用于保證提交順序
                Thread.sleep(500);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 3.關(guān)閉線程池
            threadPoolExecutor.shutdown();
        }
    }
}

其中循環(huán)了6次,讓線程池執(zhí)行了6次任務(wù),恰好滿足maximumPoolSize+workQueue容量=并發(fā)執(zhí)行任務(wù)數(shù)。輸出結(jié)果如下:

大家好,我是線程:1
大家好,我是線程:2
大家好,我是線程:5
大家好,我是線程:6
線程:1運(yùn)行完畢
大家好,我是線程:3
線程:2運(yùn)行完畢
大家好,我是線程:4
線程:5運(yùn)行完畢
線程:6運(yùn)行完畢
線程:3運(yùn)行完畢
線程:4運(yùn)行完畢

這段輸出看似沒有規(guī)律,其實(shí)這里輸出完全是由線程池控制的;下面就來分行解析輸出:

大家好,我是線程:1
大家好,我是線程:2
大家好,我是線程:5
大家好,我是線程:6

1.全新線程池被創(chuàng)建后,有Runnable或CallBack接口的實(shí)現(xiàn)被提交給線程池執(zhí)行;線程池的corePoolSize=2,此時(shí)前兩個(gè)任務(wù)提交后就立即執(zhí)行,便輸出了線程1 線程2;

2.此時(shí)仍繼續(xù)向線程池提交任務(wù),線程池中workQueue容量=2,被加入的任務(wù)存放到任務(wù)隊(duì)列中,即把線程3 線程4存放到了任務(wù)隊(duì)列中;

3.任務(wù)隊(duì)列充滿后,仍繼續(xù)向線程池提交任務(wù),線程池的maximumPoolSize=4,除開核心線程數(shù)2個(gè)外還允許創(chuàng)建4-2個(gè)線程來執(zhí)行任務(wù),便輸出了線程5 線程6

線程:1運(yùn)行完畢
大家好,我是線程:3
線程:2運(yùn)行完畢
大家好,我是線程:4

1.線程:1運(yùn)行完畢:表示第一個(gè)線程任務(wù)執(zhí)行完畢了

2.大家好,我是線程:3:線程1運(yùn)行完畢后,此時(shí)線程池中有一個(gè)空閑的線程,第一個(gè)進(jìn)入任務(wù)隊(duì)列中的任務(wù)第一個(gè)交給線程處理

3.線程:2運(yùn)行完畢 大家好,我是線程:4 :和上面線程執(zhí)行完畢,任務(wù)對列中任務(wù)執(zhí)行一致

線程:5運(yùn)行完畢
線程:6運(yùn)行完畢
線程:3運(yùn)行完畢
線程:4運(yùn)行完畢

因?yàn)槊恳粋€(gè)任務(wù)的執(zhí)行時(shí)間控制的是一樣的,此時(shí)輸出的內(nèi)容便是先被線程池執(zhí)行的任務(wù)先執(zhí)行完畢。

四、總結(jié)

線程池剛被創(chuàng)建時(shí),只是向系統(tǒng)申請一個(gè)用于執(zhí)行線程隊(duì)列和管理線程池的資源。在調(diào)用execute()添加一個(gè)任務(wù)時(shí),線程池會(huì)按照以下流程執(zhí)行任務(wù):

正在運(yùn)行的線程數(shù)量a:a<corePoolSize,線程池立即創(chuàng)建線程并執(zhí)行任務(wù);若此時(shí)a=corePoolSize,則任務(wù)被存放到workQueue任務(wù)隊(duì)列中,直到任務(wù)隊(duì)列被充滿

任務(wù)隊(duì)列workQueue已充滿且正在運(yùn)行的線程數(shù)a:a<maximumPoolSize,線程池立即創(chuàng)建非核心線程并執(zhí)行任務(wù);若有任務(wù)執(zhí)行完畢,該任務(wù)將被線程池隊(duì)列中移除,線程池從隊(duì)列中取先入隊(duì)的任務(wù)執(zhí)行;當(dāng)線程處于空閑狀態(tài)的時(shí)間超過keepAliveTime時(shí)間時(shí),正在運(yùn)行的線程數(shù)acorePoolSize<a,線程池停止空閑的線程。線程池將任務(wù)執(zhí)行完畢后,線程池會(huì)收縮到corePoolSize大小

任務(wù)隊(duì)列workQueue已充滿且正在運(yùn)行的線程數(shù)a:a=maximumPoolSize,線程池拒絕執(zhí)行該任務(wù)并拋出RejectExecutionException異常

在這里插入圖片描述

到此這篇關(guān)于淺談Java ThreadPoolExecutor的使用的文章就介紹到這了,更多相關(guān)Java ThreadPoolExecutor內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mybatis?Mapper中多參數(shù)方法不使用@param注解報(bào)錯(cuò)的解決

    Mybatis?Mapper中多參數(shù)方法不使用@param注解報(bào)錯(cuò)的解決

    這篇文章主要介紹了Mybatis?Mapper中多參數(shù)方法不使用@param注解報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
    2022-01-01
  • IDEA自動(dòng)清理類中未使用的import包的操作方法

    IDEA自動(dòng)清理類中未使用的import包的操作方法

    在項(xiàng)目開發(fā)中,經(jīng)常會(huì)引入很多未使用的import包,這不僅增加了編譯時(shí)間,還會(huì)使代碼可讀性變差,設(shè)置IDEA自動(dòng)清理未使用的import包,可以提高代碼的可讀性,本文給大家介紹IDEA自動(dòng)清理類中未使用的import包的方法,感興趣的朋友一起看看吧
    2024-09-09
  • Java接口的本質(zhì)解析

    Java接口的本質(zhì)解析

    Java接口是初學(xué)者必須經(jīng)歷的基礎(chǔ),但初學(xué)之時(shí)肯定不會(huì)完全懂,溫故而知新本篇文章就帶你重拾接口全面掌握
    2022-03-03
  • Spring Cloud Feign組件實(shí)例解析

    Spring Cloud Feign組件實(shí)例解析

    這篇文章主要介紹了Spring Cloud Feign組件實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • C語言中下標(biāo)與指針的轉(zhuǎn)換以及指向指針的指針的例子

    C語言中下標(biāo)與指針的轉(zhuǎn)換以及指向指針的指針的例子

    這篇文章主要介紹了C語言中下標(biāo)與指針的轉(zhuǎn)換以及指向指針的指針的示例,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • java實(shí)現(xiàn)網(wǎng)上購物車程序

    java實(shí)現(xiàn)網(wǎng)上購物車程序

    這篇文章主要介紹了java實(shí)現(xiàn)網(wǎng)上購物車程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • JAVA多線程中join()方法的使用方法

    JAVA多線程中join()方法的使用方法

    雖然關(guān)于討論線程join()方法的博客已經(jīng)非常極其特別多了,但是前幾天我有一個(gè)困惑卻沒有能夠得到詳細(xì)解釋,當(dāng)系統(tǒng)中正在運(yùn)行多個(gè)線程時(shí),join()到底是暫停了哪些線程,所以本文詳細(xì)解釋一下希望能幫助到和我有相同困惑的同學(xué)
    2021-05-05
  • spring boot實(shí)戰(zhàn)之本地jar包引用示例

    spring boot實(shí)戰(zhàn)之本地jar包引用示例

    本篇文章主要介紹了spring boot實(shí)戰(zhàn)之本地jar包引用示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • Java 實(shí)現(xiàn)將List平均分成若干個(gè)集合

    Java 實(shí)現(xiàn)將List平均分成若干個(gè)集合

    這篇文章主要介紹了Java 實(shí)現(xiàn)將List平均分成若干個(gè)集合,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • java實(shí)現(xiàn)五子棋小游戲

    java實(shí)現(xiàn)五子棋小游戲

    這篇文章主要介紹了java實(shí)現(xiàn)五子棋小游戲的相關(guān)資料,十分簡單實(shí)用,推薦給大家,需要的朋友可以參考下
    2015-03-03

最新評論