詳解什么是Java線程池的拒絕策略?
一、拒絕策略
(JDK提供了4種,另外也可以自定義拒絕策略,因此總共有5種。)
線程池中的線程已經(jīng)用完了,無(wú)法繼續(xù)為新任務(wù)服務(wù),同時(shí),等待隊(duì)列也已經(jīng)排滿了,再也塞不下新任務(wù)了。這時(shí)候我們就需要拒絕策略機(jī)制合理的處理這個(gè)問(wèn)題。
JDK 內(nèi)置的拒絕策略如下:
1.AbortPolicy : 直接拋出異常,阻止系統(tǒng)正常運(yùn)行。
2.CallerRunsPolicy : 只要線程池未關(guān)閉,該策略直接在調(diào)用者線程中,運(yùn)行當(dāng)前被丟棄的任務(wù)。顯然這樣做不會(huì)真的丟棄任務(wù),但是,任務(wù)提交線程的性能極有可能會(huì)急劇下降。
3.DiscardPolicy : 該策略默默地丟棄無(wú)法處理的任務(wù),不予任何處理。如果允許任務(wù)丟失,這是最好的一種方案。
4.DiscardOldestPolicy : 丟棄最老的一個(gè)請(qǐng)求,也就是即將被執(zhí)行的一個(gè)任務(wù),并嘗試再次提交當(dāng)前任務(wù)。
以上內(nèi)置拒絕策略均實(shí)現(xiàn)了 RejectedExecutionHandler 接口,若以上策略仍無(wú)法滿足實(shí)際需要,完全可以自己擴(kuò)展 RejectedExecutionHandler 接口。
1.1 AbortPolicy(默認(rèn)拒絕策略)
(也可以沒(méi)有new ThreadPoolExecutor.AbortPolicy() 這個(gè)參數(shù) ,隱式的默認(rèn)拒絕策略)
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ThreadDemo58 { public static void main(String[] args) { // 創(chuàng)建線程池 ThreadPoolExecutor executor = new ThreadPoolExecutor( 5, 5, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>(5), new ThreadPoolExecutor.AbortPolicy()); for (int i = 0; i < 11; i++) { int finalI = i; executor.execute(new Runnable() { @Override public void run() { System.out.println("任務(wù):" + finalI + ",線程名:" + Thread.currentThread().getName()); } }); } } }
1.2 CallerRunsPolicy(使用調(diào)用線程池的線程來(lái)執(zhí)行任務(wù) )
(即使用主線程來(lái)執(zhí)行任務(wù))
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ThreadDemo59 { public static void main(String[] args) throws InterruptedException { // 創(chuàng)建線程池 ThreadPoolExecutor executor = new ThreadPoolExecutor( 5, 5, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>(5), new ThreadPoolExecutor.CallerRunsPolicy()); for (int i = 0; i < 11; i++) { int finalI = i; executor.execute(new Runnable() { @Override public void run() { System.out.println("任務(wù):" + finalI + ",線程名:" + Thread.currentThread().getName()); } }); // Thread.sleep(200); } } }
1.3 DiscardPolicy (忽略新任務(wù))
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ThreadDemo59 { public static void main(String[] args) throws InterruptedException { // 創(chuàng)建線程池 ThreadPoolExecutor executor = new ThreadPoolExecutor( 5, 5, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>(5), new ThreadPoolExecutor.AbortPolicy()); for (int i = 0; i < 11; i++) { int finalI = i; executor.execute(new Runnable() { @Override public void run() { System.out.println("任務(wù):" + finalI + ",線程名:" + Thread.currentThread().getName()); } }); } } }
1.4 DiscardOldestPolicy(忽略老任務(wù))
(老任務(wù)指第一個(gè)進(jìn)入阻塞隊(duì)列里的)
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ThreadDemo59 { public static void main(String[] args) throws InterruptedException { // 創(chuàng)建線程池 ThreadPoolExecutor executor = new ThreadPoolExecutor( 5, 5, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>(5), new ThreadPoolExecutor.DiscardOldestPolicy()); for (int i = 0; i < 11; i++) { int finalI = i; executor.execute(new Runnable() { @Override public void run() { System.out.println("任務(wù):" + finalI + ",線程名:" + Thread.currentThread().getName()); } }); } } }
1.5 自定義拒絕策略
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ThreadDemo60 { public static void main(String[] args) throws InterruptedException { // 創(chuàng)建線程池 ThreadPoolExecutor executor = new ThreadPoolExecutor( 5, 5, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>(5), new RejectedExecutionHandler() { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { // 自定義拒絕策略 System.out.println("執(zhí)行了自定義拒絕策略"); } }); for (int i = 0; i < 11; i++) { int finalI = i; executor.execute(new Runnable() { @Override public void run() { System.out.println("任務(wù):" + finalI + ",線程名:" + Thread.currentThread().getName()); } }); } } }
到此這篇關(guān)于詳解什么是線程池的拒絕策略?的文章就介紹到這了,更多相關(guān)線程池的拒絕策略內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何用java計(jì)算兩個(gè)時(shí)間相差多少小時(shí)
最近工作中遇到需要計(jì)算時(shí)間差,下面這篇文章主要給大家介紹了關(guān)于如何用java計(jì)算兩個(gè)時(shí)間相差多少小時(shí)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12SpringBoot中的@Conditional?注解的使用
@Conditional是Spring4新提供的注解,它的作用是按照一定的條件進(jìn)行判斷,滿足條件的才給容器注冊(cè)Bean,本文主要介紹了SpringBoot中的@Conditional?注解的使用2024-01-01java數(shù)據(jù)結(jié)構(gòu)與算法之noDups去除重復(fù)項(xiàng)算法示例
這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)與算法之noDups去除重復(fù)項(xiàng)算法實(shí)現(xiàn)技巧,程序代碼非常簡(jiǎn)單,關(guān)鍵在于循環(huán)與判定,需要的朋友可以參考下2016-08-08IntelliJ IDEA cmd和idea Terminal查看java版本不一致的解決
原來(lái)win10電腦上安裝的是jdk8的版本,因某些原因,現(xiàn)在想換成jdk7的版本,修改環(huán)境變量后,在cmd中執(zhí)行 [java -version]命令,顯示的是7的版本,遇到這樣的問(wèn)題如何解決呢?下面小編給大家分享IntelliJ IDEA cmd和idea Terminal查看java版本不一致的解決方案,一起看看吧2023-09-09