當ThreadPoolExecutor中的線程都已經忙於執行,且有界隊列也滿了,這個時候就需要自己寫reject策略;此處給一個demo,供大家去理解和參考:
1、先寫一個可執行的線程
package zhengchao_001_005.ThreadPoolExecutor;
public class Task implements Runnable{
private int id ;
private String name ;
public Task(int id, String name){
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void run() {
//
System.out.println("當前線程id和名稱爲:" + this.id +", " + this.name);
try {
Thread.sleep(5*1000);
} catch (Exception e) {
e.printStackTrace();
}
}
public String toString(){
return "{ id : " + this.id + ", name : " + this.name + "}";
}
}
2、我們寫一個RejectedExecutionHandler,必須要實現RejectedExecutionHandler接口,並實現他的rejectedExecution()方法
兩個參數,一個是需要拒絕的線程,另一個是我們的線程池,至於如何拒絕,按照自己的業務邏輯去進行處理,
package zhengchao_001_005.ThreadPoolExecutor;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
public class MyRejected implements RejectedExecutionHandler{
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println("自定義拒絕處理_"+r.toString());
}
}
3、測試用例
package zhengchao_001_005.ThreadPoolExecutor;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TestThreadPoolExecutor {
public static void main(String[] args) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
1, //核心的線程數量
1, //最大的線程數量
10, //空閒數值
TimeUnit.SECONDS, //空閒時間單位
new ArrayBlockingQueue<Runnable>(3),//有界隊列
new MyRejected()
);
Task t1 = new Task(1, "任務" + 1);
Task t2 = new Task(2, "任務" + 2);
Task t3 = new Task(3, "任務" + 3);
Task t4 = new Task(4, "任務" + 4);
Task t5 = new Task(5, "任務" + 5);
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//System.out.println(pool.getQueue().size());
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
運行結果:
自定義拒絕處理_{ id : 5, name : 任務5}
當前線程id和名稱爲:1, 任務1
當前線程id和名稱爲:2, 任務2
當前線程id和名稱爲:3, 任務3
當前線程id和名稱爲:4, 任務4
注意點:
如果使用LinkedBlockingQueue則不會有隊列滿的問題,LinkedBlockingQueue直到系統資源耗盡纔會出問題,但這種體驗可能會比較差,至於用哪種好,仁者見仁,不是,業務爲前提。