当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直到系统资源耗尽才会出问题,但这种体验可能会比较差,至于用哪种好,仁者见仁,不是,业务为前提。