詳解什么是Java線程池的拒絕策略?
一、拒絕策略
(JDK提供了4種,另外也可以自定義拒絕策略,因此總共有5種。)
線程池中的線程已經(jīng)用完了,無法繼續(xù)為新任務(wù)服務(wù),同時,等待隊列也已經(jīng)排滿了,再也塞不下新任務(wù)了。這時候我們就需要拒絕策略機(jī)制合理的處理這個問題。
JDK 內(nèi)置的拒絕策略如下:
1.AbortPolicy : 直接拋出異常,阻止系統(tǒng)正常運(yùn)行。
2.CallerRunsPolicy : 只要線程池未關(guān)閉,該策略直接在調(diào)用者線程中,運(yùn)行當(dāng)前被丟棄的任務(wù)。顯然這樣做不會真的丟棄任務(wù),但是,任務(wù)提交線程的性能極有可能會急劇下降。
3.DiscardPolicy : 該策略默默地丟棄無法處理的任務(wù),不予任何處理。如果允許任務(wù)丟失,這是最好的一種方案。
4.DiscardOldestPolicy : 丟棄最老的一個請求,也就是即將被執(zhí)行的一個任務(wù),并嘗試再次提交當(dāng)前任務(wù)。
以上內(nèi)置拒絕策略均實(shí)現(xiàn)了 RejectedExecutionHandler 接口,若以上策略仍無法滿足實(shí)際需要,完全可以自己擴(kuò)展 RejectedExecutionHandler 接口。
1.1 AbortPolicy(默認(rèn)拒絕策略)
(也可以沒有new ThreadPoolExecutor.AbortPolicy() 這個參數(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)用線程池的線程來執(zhí)行任務(wù) )
(即使用主線程來執(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ù)指第一個進(jìn)入阻塞隊列里的)
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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中的@Conditional?注解的使用
@Conditional是Spring4新提供的注解,它的作用是按照一定的條件進(jìn)行判斷,滿足條件的才給容器注冊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)技巧,程序代碼非常簡單,關(guān)鍵在于循環(huán)與判定,需要的朋友可以參考下2016-08-08IntelliJ IDEA cmd和idea Terminal查看java版本不一致的解決
原來win10電腦上安裝的是jdk8的版本,因某些原因,現(xiàn)在想換成jdk7的版本,修改環(huán)境變量后,在cmd中執(zhí)行 [java -version]命令,顯示的是7的版本,遇到這樣的問題如何解決呢?下面小編給大家分享IntelliJ IDEA cmd和idea Terminal查看java版本不一致的解決方案,一起看看吧2023-09-09