Java線程池的四種拒絕策略詳解
dk1.5版本新增了 JUC 并發(fā)包,其中一個包含線程池。
四種拒絕策略:
拒絕策略類型 | 說明 | |
---|---|---|
1 | ThreadPoolExecutor.AbortPolicy | 默認拒絕策略,拒絕任務(wù)并拋出任務(wù) |
2 | ThreadPoolExecutor.CallerRunsPolicy | 使用調(diào)用線程直接運行任務(wù) |
3 | ThreadPoolExecutor.DiscardPolicy | 直接拒絕任務(wù),不拋出錯誤 |
4 | ThreadPoolExecutor.DiscardOldestPolicy | 觸發(fā)拒絕策略,只要還有任務(wù)新增,一直會丟棄阻塞隊列的最老的任務(wù),并將新的任務(wù)加入 |
預(yù)先配置
配置線程池。
- 核心線程和最大線程都盡量設(shè)置的小一點,分別設(shè)置成 1 和 2
- 阻塞隊列設(shè)置固定長度的有界隊列,長度為 1
- 線程工廠設(shè)置默認線程工廠
// 核心線程數(shù) int corePoolSize = 1; // 最大線程數(shù) int maximumPoolSize = 2; // 線程存活時間 long keepAliveTime = 10; // 線程存活時間單位 TimeUnit unit = TimeUnit.SECONDS; // 有界隊列 遵循 FIFO 原則 BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(1); // 線程工廠 ThreadFactory threadFactory = Executors.defaultThreadFactory();
創(chuàng)建線程任務(wù)
創(chuàng)建線程任務(wù),一個線程任務(wù)執(zhí)行一秒:
class TaskThread implements Runnable{ private int i; public TaskThread(int i) { this.i = i; } @Override public void run() { try { TimeUnit.SECONDS.sleep(2); System.out.println("執(zhí)行任務(wù):" + i); } catch (InterruptedException e) { e.printStackTrace(); } } }
拒絕策略一:AbortPolicy
默認拒絕策略,拒絕任務(wù)并拋出任務(wù)
// 拒絕策略 默認拒絕策略,拒絕任務(wù)并拋出異常: RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); for (int i = 1; i <= 5; i++) { try { threadPool.execute(new TaskThread(i)); } catch (Exception e) { System.out.println("【任務(wù)" + i + "】報錯:" + e.getMessage()); } }
輸出
【任務(wù)】4報錯:Task com.test.controller.ThreadPoolController$TaskThread@5c0369c4 rejected from java.util.concurrent.ThreadPoolExecutor@50675690[Running, pool size = 2, active threads = 2, queued tasks = 1, completed tasks = 0]
【任務(wù)】5報錯:Task com.test.controller.ThreadPoolController$TaskThread@31b7dea0 rejected from java.util.concurrent.ThreadPoolExecutor@50675690[Running, pool size = 2, active threads = 2, queued tasks = 1, completed tasks = 0]
執(zhí)行任務(wù):1
執(zhí)行任務(wù):3
執(zhí)行任務(wù):2
最大線程數(shù) + 阻塞隊列 = 3,執(zhí)行到4,5的時候就拋出錯誤。這里需要用 try catch 捕獲異常。任務(wù)1、2、3正常執(zhí)行。
如果提交的任務(wù)都要執(zhí)行,可以將拋出的錯誤任務(wù)存入在redis中,然后定時從redis中獲取任務(wù),再提交執(zhí)行。
拒絕策略二:CallerRunsPolicy
調(diào)用線程運行多余的任務(wù)。
更換拒絕策略,將上面的 AbortPolicy 換成 CallerRunsPolicy。
RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
執(zhí)行任務(wù),輸出:
執(zhí)行任務(wù):1
執(zhí)行任務(wù):4
執(zhí)行任務(wù):3
執(zhí)行任務(wù):2
執(zhí)行任務(wù):5
最大線程數(shù) + 阻塞隊列 = 3,多余的任務(wù)還是繼續(xù)被執(zhí)行。
拒絕策略三:DiscardPolicy
拒絕任務(wù),不會拋出錯誤。
更換策略,將CallerRunsPolicy 換成DiscardPolicy:
RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
執(zhí)行任務(wù),輸出:
執(zhí)行任務(wù):1
執(zhí)行任務(wù):3
執(zhí)行任務(wù):2
MAKEFILE 復(fù)制 全屏
多余的線程任務(wù)提交被拒絕,而只執(zhí)行最大線程數(shù) + 阻塞隊列 數(shù)量的任務(wù),并且不會拋出錯誤。
拒絕策略四:DiscardOldestPolicy
只要還有任務(wù)新增,一直會丟棄阻塞隊列的最老的任務(wù),并將新的任務(wù)加入到阻塞隊列中。
更換策略,將DiscardPolicy 換成DiscardOldestPolicy:
RejectedExecutionHandler handler3 = new ThreadPoolExecutor.DiscardOldestPolicy();
執(zhí)行任務(wù),輸出:
執(zhí)行任務(wù):3
執(zhí)行任務(wù):1
執(zhí)行任務(wù):5
任務(wù)的執(zhí)行順序是 核心線程數(shù) —> 阻塞隊列 —> 最大線程數(shù),其中任務(wù)1,任務(wù)3提交成功。
- 任務(wù)2因為在阻塞隊列中,
- 后面的任務(wù)4把任務(wù)2擠掉,
- 任務(wù)5又把任務(wù)4擠掉,所以最后執(zhí)行的是任務(wù)5。
總結(jié)
本文介紹了線程四種拒絕策略,當工作任務(wù)大于最大線程 + 阻塞隊列會執(zhí)行阻塞隊列。
- AbortPolicy 默認策略,拒絕任務(wù),并拋出異常
- CallerRunsPolicy 調(diào)用線程執(zhí)行對于的任務(wù)
- DiscardPolicy 拒絕任務(wù),不會拋出異常
- DiscardOldestPolicy 有多余的任務(wù),把阻塞隊列最老的任務(wù)丟棄,放入新的任務(wù),直到?jīng)]有新的任務(wù)。
到此這篇關(guān)于Java線程池的四種拒絕策略的文章就介紹到這了,更多相關(guān)Java 線程池拒絕策略內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java ThreadPool線程池的使用,線程池工具類用法說明
這篇文章主要介紹了java ThreadPool線程池的使用,線程池工具類用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10java執(zhí)行SQL語句實現(xiàn)查詢的通用方法詳解
這篇文章主要介紹了java執(zhí)行SQL語句實現(xiàn)查詢的通用方法詳解,具有一定借鑒價值,需要的朋友可以參考下。2017-12-12基于Rest的API解決方案(jersey與swagger集成)
下面小編就為大家?guī)硪黄赗est的API解決方案(jersey與swagger集成)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08springboot 啟動如何修改application.properties的參數(shù)
這篇文章主要介紹了springboot 啟動如何修改application.properties的參數(shù)方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08