最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Java?ThreadPoolExecutor的拒絕策略

 更新時(shí)間:2022年08月29日 16:25:42   作者:劍圣無痕  
這篇文章主要介紹了Java?ThreadPoolExecutor的拒絕策略,本文對(duì)于線程的池的幾種策略進(jìn)行詳細(xì)的講解,在實(shí)際的生產(chǎn)中需要集合相關(guān)的場(chǎng)景來選擇合適的拒絕策略,需要的朋友可以參考下

背景

線程池的技術(shù)在項(xiàng)目中使用廣泛,線程池提供了四種拒絕策略,大家是否了解這四種拒絕的策略呢?本文將詳細(xì)的講解ThreadPoolExecutor的四種拒絕策略,以及相關(guān)的注意事項(xiàng)。

線程池基本原理

線程池的原理如下圖:

說明:

  • 當(dāng)前運(yùn)行的線程少于corePoolSize,則創(chuàng)建新線程來執(zhí)行任務(wù)。
  • 運(yùn)行的線程等于或多于corePoolSize,則將任務(wù)添加到隊(duì)列中。
  • 當(dāng)任務(wù)隊(duì)列已滿,則在非corePool中創(chuàng)建新的線程來處理任務(wù)。
  • 創(chuàng)建新線程將使當(dāng)前運(yùn)行的線程超出maximumPoolSize,任務(wù)將被拒絕,并調(diào)用RejectedExecutionHandler.rejectedExecution()方法。

線程池拒絕策略

線程池為我們提供了四種拒絕策略分別是:CallerRunsPolicy,AbortPolicy,DiscardPolicy,DiscardOldestPolicy

AbortPolicy

ThreadPoolExecutor中默認(rèn)的拒絕策略就是AbortPolicy直接拋出異常,具體實(shí)現(xiàn)如下

public static class AbortPolicy implements RejectedExecutionHandler {
    public AbortPolicy() { }
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        throw new RejectedExecutionException("Task " + r.toString() +
                                             " rejected from " +
                                             e.toString());
    }
}

說明:這種策略非常簡(jiǎn)單粗暴,直接拋出RejectedExecutionException異常,也不會(huì)執(zhí)行后續(xù)的任務(wù)。

示例說明:

public class ThreadPoolTest
{
    public static void main(String[] args)
    {
        ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                2,
                5,
                10,
                TimeUnit.MICROSECONDS,
                new LinkedBlockingDeque<>(1),
                new ThreadPoolExecutor.AbortPolicy());
        
        //異步執(zhí)行
        for(int i=0; i<10;i++)
        {
          System.out.println("添加第"+i+"個(gè)任務(wù)");
          threadPoolExecutor.execute(new TestThread("線程"+i));
        }        
    }
}

public class TestThread implements Runnable
{
    private String name;
    public TestThread(String name){
        this.name=name;
    }
    
    @Override
    public void run()
    {
        try
        {
            Thread.sleep(1000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        System.out.println("thread name:"+Thread.currentThread().getName()+",執(zhí)行:"+name);
    }
}

執(zhí)行結(jié)果:

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.skywares.fw.juc.thread.TestThread@55f96302 rejected from java.util.concurrent.ThreadPoolExecutor@3d4eac69[Running, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
    at com.skywares.fw.juc.thread.ThreadPoolTest.main(ThreadPoolTest.java:26)
thread name:pool-1-thread-5,執(zhí)行:線程5
thread name:pool-1-thread-2,執(zhí)行:線程1
thread name:pool-1-thread-4,執(zhí)行:線程4
thread name:pool-1-thread-3,執(zhí)行:線程3
thread name:pool-1-thread-1,執(zhí)行:線程0
thread name:pool-1-thread-5,執(zhí)行:線程2

從執(zhí)行結(jié)果我們得知,采用AbortPolicy策略當(dāng)任務(wù)執(zhí)行到第七個(gè)任務(wù)時(shí)會(huì)直接報(bào)錯(cuò),導(dǎo)致后續(xù)的業(yè)務(wù)邏輯不會(huì)執(zhí)行。

CallerRunsPolicy

CallerRunsPolicy在任務(wù)被拒絕添加后,會(huì)用調(diào)用execute函數(shù)的上層線程去執(zhí)行被拒絕的任務(wù)。

相關(guān)示例

public class ThreadPoolTest
{
    public static void main(String[] args)
    {
        ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                2,
                5,
                10,
                TimeUnit.MICROSECONDS,
                new LinkedBlockingDeque<>(1),
                new ThreadPoolExecutor.CallerRunsPolicy());
        
        //異步執(zhí)行
        for(int i=0; i<10;i++)
        {
          System.out.println("添加第"+i+"個(gè)任務(wù)");
          threadPoolExecutor.execute(new TestThread("線程"+i));
        }
    }
}

執(zhí)行結(jié)果:

添加第0個(gè)任務(wù)
添加第1個(gè)任務(wù)
添加第2個(gè)任務(wù)
添加第3個(gè)任務(wù)
添加第4個(gè)任務(wù)
添加第5個(gè)任務(wù)
添加第6個(gè)任務(wù)
thread name:main,執(zhí)行:線程6
thread name:pool-1-thread-3,執(zhí)行:線程3
thread name:pool-1-thread-1,執(zhí)行:線程0
thread name:pool-1-thread-4,執(zhí)行:線程4
thread name:pool-1-thread-2,執(zhí)行:線程1
thread name:pool-1-thread-5,執(zhí)行:線程5
添加第7個(gè)任務(wù)
添加第8個(gè)任務(wù)
thread name:main,執(zhí)行:線程8
thread name:pool-1-thread-1,執(zhí)行:線程7
thread name:pool-1-thread-3,執(zhí)行:線程2
添加第9個(gè)任務(wù)
thread name:pool-1-thread-1,執(zhí)行:線程9

從執(zhí)行的結(jié)果我們可以得知,當(dāng)執(zhí)行到第7個(gè)任務(wù)時(shí),由于線程池拒絕策略,此任務(wù)由主線程來執(zhí)行,當(dāng)線程池有空閑時(shí),才繼續(xù)執(zhí)行其他的任務(wù)。所以此策略可能會(huì)阻塞主線程。

DiscardPolicy

這種拒絕策略比較簡(jiǎn)單,線程池拒絕的任務(wù)直接拋棄,不會(huì)拋異常也不會(huì)執(zhí)行

示例

修改上述的代碼,將拒絕策略修改為DiscardPolicy

 ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                2,
                5,
                10,
                TimeUnit.MICROSECONDS,
                new LinkedBlockingDeque<>(1),
                new ThreadPoolExecutor.CallerRunsPolicy());

執(zhí)行結(jié)果

invoke dealStock success
goodsId:手機(jī)
thread name:pool-1-thread-1,執(zhí)行:線程0
thread name:pool-1-thread-4,執(zhí)行:線程4
thread name:pool-1-thread-5,執(zhí)行:線程5
thread name:pool-1-thread-3,執(zhí)行:線程3
thread name:pool-1-thread-2,執(zhí)行:線程1
thread name:pool-1-thread-1,執(zhí)行:線程2

從執(zhí)行的結(jié)果來看只執(zhí)行了6個(gè)任務(wù),其他的任務(wù)都被拋棄了。

DiscardOldestPolicy

DiscardOldestPolicy 當(dāng)任務(wù)拒絕添加時(shí),會(huì)拋棄任務(wù)隊(duì)列中最先加入隊(duì)列的任務(wù),再把新任務(wù)添加進(jìn)去。

示例說明

 ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                1,
                2,
                10,
                TimeUnit.MICROSECONDS,
                new LinkedBlockingDeque<>(2),
                new ThreadPoolExecutor.CallerRunsPolicy());

執(zhí)行結(jié)果:

添加第0個(gè)任務(wù)
添加第1個(gè)任務(wù)
添加第2個(gè)任務(wù)
添加第3個(gè)任務(wù)
添加第4個(gè)任務(wù)
添加第5個(gè)任務(wù)
invoke dealStock success
goodsId:手機(jī)
thread name:pool-1-thread-2,執(zhí)行:線程3
thread name:pool-1-thread-1,執(zhí)行:線程0
thread name:pool-1-thread-1,執(zhí)行:線程2
thread name:pool-1-thread-2,執(zhí)行:線程1

自定義拒絕策略

當(dāng)線程池提供的拒絕策略無法滿足要求時(shí),我們可以采用自定義的拒絕策略,只需要實(shí)現(xiàn)RejectedExecutionHandler接口即可

public class CustRejectedExecutionHandler implements RejectedExecutionHandler
{
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
    {
        new Thread(r,"線程:"+new Random().nextInt(10)).start();
    }
}

  ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                1,
                2,
                10,
                TimeUnit.MICROSECONDS,
                new LinkedBlockingDeque<>(2),
                new CustRejectedExecutionHandler());

執(zhí)行結(jié)果:

thread name:客戶線程:6,執(zhí)行:線程5
thread name:pool-1-thread-1,執(zhí)行:線程0
thread name:客戶線程:8,執(zhí)行:線程4
thread name:pool-1-thread-2,執(zhí)行:線程3
thread name:pool-1-thread-1,執(zhí)行:線程1
thread name:pool-1-thread-2,執(zhí)行:線程2

從執(zhí)行的結(jié)果來看,被拒絕的任務(wù)都在客戶的新線程中執(zhí)行。

小結(jié)

  • AbortPolicy:直接拋出異常,后續(xù)的任務(wù)不會(huì)執(zhí)行
  • CallerRunsPolicy:子任務(wù)執(zhí)行的時(shí)間過長(zhǎng),可能會(huì)阻塞主線程。
  • DiscardPolicy:不拋異常,任務(wù)直接丟棄
  • DiscardOldestPolicy;丟棄最先加入隊(duì)列的任務(wù)

總結(jié)

本文對(duì)于線程的池的幾種策略進(jìn)行詳細(xì)的講解,在實(shí)際的生產(chǎn)中需要集合相關(guān)的場(chǎng)景來選擇合適的拒絕策略,如有疑問,請(qǐng)隨時(shí)反饋。

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

相關(guān)文章

  • Java實(shí)現(xiàn)JDBC批量插入原理詳解

    Java實(shí)現(xiàn)JDBC批量插入原理詳解

    在JDBC中,executeBatch這個(gè)方法可以將多條dml語句批量執(zhí)行,效率比單條執(zhí)行executeUpdate高很多,這是什么原理呢?在mysql和oracle中又是如何實(shí)現(xiàn)批量執(zhí)行的呢?本文將給大家介紹這背后的原理
    2023-03-03
  • java數(shù)據(jù)結(jié)構(gòu)基礎(chǔ):循環(huán)鏈表和棧

    java數(shù)據(jù)結(jié)構(gòu)基礎(chǔ):循環(huán)鏈表和棧

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之循環(huán)鏈表、棧的實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了Java數(shù)據(jù)結(jié)構(gòu)中循環(huán)鏈表、棧、的功能、定義及使用方法,需要的朋友可以參考下
    2021-08-08
  • 詳解Jackson 使用以及性能介紹

    詳解Jackson 使用以及性能介紹

    這篇文章主要介紹了詳解Jackson 使用以及性能介紹,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java實(shí)現(xiàn)摳圖片文字或簽名的完整代碼

    Java實(shí)現(xiàn)摳圖片文字或簽名的完整代碼

    這篇文章主要介紹了java摳圖片文字或簽名的運(yùn)行原理,本文分步驟通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • MyBatis超詳細(xì)講解如何實(shí)現(xiàn)分頁功能

    MyBatis超詳細(xì)講解如何實(shí)現(xiàn)分頁功能

    MyBatis-Plus?是一個(gè)?Mybatis?增強(qiáng)版工具,在?MyBatis?上擴(kuò)充了其他功能沒有改變其基本功能,為了簡(jiǎn)化開發(fā)提交效率而存在,本篇文章帶用它實(shí)現(xiàn)分頁功能
    2022-03-03
  • windows下jar包開機(jī)自動(dòng)重啟的步驟

    windows下jar包開機(jī)自動(dòng)重啟的步驟

    這篇文章主要給大家介紹了關(guān)于windows下jar包開機(jī)自動(dòng)重啟的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Spring Security基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)認(rèn)證過程解析

    Spring Security基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)認(rèn)證過程解析

    這篇文章主要介紹了Spring Security基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)認(rèn)證過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • java創(chuàng)建多級(jí)目錄文件的實(shí)例講解

    java創(chuàng)建多級(jí)目錄文件的實(shí)例講解

    下面小編就為大家分享一篇java創(chuàng)建多級(jí)目錄文件的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • Java中集合關(guān)系圖及常見操作詳解

    Java中集合關(guān)系圖及常見操作詳解

    這篇文章主要為大家詳細(xì)介紹了Java中集合關(guān)系圖及常見操作,解析Java中的集合類型的繼承關(guān)系圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Spring MVC注解式開發(fā)使用詳解

    Spring MVC注解式開發(fā)使用詳解

    本篇文章主要介紹了Spring MVC注解式開發(fā)使用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-03-03

最新評(píng)論

和平区| 贵南县| 巴东县| 社旗县| 崇明县| 微山县| 敖汉旗| 万载县| 古浪县| 密山市| 宜宾市| 黎平县| 镇康县| 六盘水市| 湖州市| 和静县| 波密县| 日土县| 扶绥县| 永州市| 牟定县| 商城县| 饶平县| 忻城县| 固镇县| 泗洪县| 曲阜市| 泰安市| 铁岭县| 达日县| 南安市| 睢宁县| 承德市| 梓潼县| 通化市| 开江县| 钟祥市| 繁峙县| 白河县| 明溪县| 达州市|