亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺談Java ThreadPoolExecutor的使用

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

一、前言

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

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

在這里插入圖片描述

二、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時,空閑線程的存活時間

4.unit:keepAliveTime的時間單位

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

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

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

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

編寫測試類如下:

public class ThreadPoolSerialTest {
    public static void main(String[] args) {
        //核心線程數(shù)
        int corePoolSize = 2;
        //最大線程數(shù)
        int maximumPoolSize = 4;
        //超過corePoolSize線程數(shù)量的線程最大空閑時間
        long keepAliveTime = 2;
        //以秒為時間單位
        TimeUnit unit = TimeUnit.SECONDS;
        //創(chuàng)建工作隊列,用于存放提交的等待執(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í)行時間,10s
                        Thread.sleep(10000);
                        System.out.println("線程:"+index+"運行完畢");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
                //每個任務(wù)提交后休眠500ms再提交下一個任務(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運行完畢
大家好,我是線程:3
線程:2運行完畢
大家好,我是線程:4
線程:5運行完畢
線程:6運行完畢
線程:3運行完畢
線程:4運行完畢

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

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

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

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

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

線程:1運行完畢
大家好,我是線程:3
線程:2運行完畢
大家好,我是線程:4

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

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

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

線程:5運行完畢
線程:6運行完畢
線程:3運行完畢
線程:4運行完畢

因為每一個任務(wù)的執(zhí)行時間控制的是一樣的,此時輸出的內(nèi)容便是先被線程池執(zhí)行的任務(wù)先執(zhí)行完畢。

四、總結(jié)

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

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

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

任務(wù)隊列workQueue已充滿且正在運行的線程數(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注解報錯的解決

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

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

    IDEA自動清理類中未使用的import包的操作方法

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

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

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

    Spring Cloud Feign組件實例解析

    這篇文章主要介紹了Spring Cloud Feign組件實例解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    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實現(xiàn)網(wǎng)上購物車程序

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

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

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

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

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

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

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

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

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

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

最新評論