为什么要使用拒绝策略?
等待队列已经排满了,再也塞不下新任务了
同时,线程池中的max线程也达到了,无法继续为新任务服务。
这个是时候我们就需要拒绝策略机制合理的处理这个问题。
四种拒绝策略介绍
jdk中自带的拒绝策略均实现了java.util.concurrent.RejectedExecutionHandler接口
AbortPolicy
默认的拒绝策略。直接抛出 java.util.concurrent.RejectedExecutionException异常
new ThreadPoolExecutor.AbortPolicy()
import java.util.concurrent.*;
public class Test {
public static void main(String[] args) {
ExecutorService executorService = new ThreadPoolExecutor(2, 5, 2, TimeUnit.SECONDS, new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
try {
for (int i = 1; i <= 9; i++) {
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 办理业务");
}
});
}
} finally {
executorService.shutdown();
}
}
}
CallerRunsPolicy
将任务返还给调用者线程执行
new ThreadPoolExecutor.CallerRunsPolicy()
import java.util.concurrent.*;
public class Test {
public static void main(String[] args) {
ExecutorService executorService = new ThreadPoolExecutor(2, 5, 2, TimeUnit.SECONDS, new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
try {
for (int i = 1; i <= 9; i++) {
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 办理业务");
}
});
}
} finally {
executorService.shutdown();
}
}
}
执行结果: 任务果然返还给main线程了
DiscardPolicy
直接抛弃无法处理的任务,不予处理不抛异常。如果业务汇总允许任务丢失,这是最好的策略
new ThreadPoolExecutor.DiscardPolicy()
查看执行结果,只有8个。第9个被抛弃
DiscardOldestPolicy
抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务
new ThreadPoolExecutor.DiscardOldestPolicy()