詳解什么是Java線程池的拒絕策略?
一、拒絕策略
(JDK提供了4種,另外也可以自定義拒絕策略,因此總共有5種。)
線程池中的線程已經(jīng)用完了,無法繼續(xù)為新任務(wù)服務(wù),同時,等待隊列也已經(jīng)排滿了,再也塞不下新任務(wù)了。這時候我們就需要拒絕策略機制合理的處理這個問題。
JDK 內(nèi)置的拒絕策略如下:
1.AbortPolicy : 直接拋出異常,阻止系統(tǒng)正常運行。
2.CallerRunsPolicy : 只要線程池未關(guān)閉,該策略直接在調(diào)用者線程中,運行當(dāng)前被丟棄的任務(wù)。顯然這樣做不會真的丟棄任務(wù),但是,任務(wù)提交線程的性能極有可能會急劇下降。
3.DiscardPolicy : 該策略默默地丟棄無法處理的任務(wù),不予任何處理。如果允許任務(wù)丟失,這是最好的一種方案。
4.DiscardOldestPolicy : 丟棄最老的一個請求,也就是即將被執(zhí)行的一個任務(wù),并嘗試再次提交當(dāng)前任務(wù)。
以上內(nèi)置拒絕策略均實現(xiàn)了 RejectedExecutionHandler 接口,若以上策略仍無法滿足實際需要,完全可以自己擴展 RejectedExecutionHandler 接口。
1.1 AbortPolicy(默認拒絕策略)
(也可以沒有new ThreadPoolExecutor.AbortPolicy() 這個參數(shù) ,隱式的默認拒絕策略)
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ù)指第一個進入阻塞隊列里的)
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)文章
Spring AI TikaDocumentReader詳解
TikaDocumentReader是SpringAI中用于從多種格式文檔中提取文本內(nèi)容的組件,支持PDF、DOC/DOCX、PPT/PPTX和HTML等格式,它在構(gòu)建知識庫、文檔處理和數(shù)據(jù)清洗等任務(wù)中非常有用2025-01-01
Springmvc ResponseBody響應(yīng)json數(shù)據(jù)實現(xiàn)過程
這篇文章主要介紹了Springmvc ResponseBody響應(yīng)json數(shù)據(jù)實現(xiàn)過程,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10
SpringBoot發(fā)送異步郵件流程與實現(xiàn)詳解
這篇文章主要介紹了SpringBoot發(fā)送異步郵件流程與實現(xiàn)詳解,Servlet階段郵件發(fā)送非常的復(fù)雜,如果現(xiàn)代化的Java開發(fā)是那個樣子該有多糟糕,現(xiàn)在SpringBoot中集成好了郵件發(fā)送的東西,而且操作十分簡單容易上手,需要的朋友可以參考下2024-01-01
java使用動態(tài)代理來實現(xiàn)AOP(日志記錄)的實例代碼
AOP(面向方面)的思想,就是把項目共同的那部分功能分離開來,比如日志記錄,避免在業(yè)務(wù)邏輯里面夾雜著跟業(yè)務(wù)邏輯無關(guān)的代碼2013-09-09
java經(jīng)典問題:連個字符串互為回環(huán)變位
連個字符串互為回環(huán)變位經(jīng)常出現(xiàn)在java程序員面試中,這個是考驗程序員的解題思路和方法的最經(jīng)典的一題,小編為大家詳細分析一下,一起來學(xué)習(xí)吧。2017-11-11

