线程池中有三个重要参数,影响拒绝策略
当提交任务数大于corePoolSize 的时候,会优先将任务放到workQueue阻塞队列中。当阻塞队列饱和后,会扩充线程池中线程数到maximumPoolSize最大线程数。此时,多余的任务,则会触发线程数的拒绝策略。
拒绝策略提供了顶级接口RejectedExecutionHander,其中方法rejectedExecution即定制具体的拒绝策略的执行逻辑。
jdk默认的4种拒绝策略
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class AbortPolicyTest {
public static void main(String[] args) {
AtomicInteger count=new AtomicInteger(0);
int corePoolSize = 2, maximumPoolSize = 5, keepAliveTime = 5;
BlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<>(10);
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime,
TimeUnit.SECONDS, workQueue, handler);
for (int i = 0; i < 100; i++) {
executor.execute(new Thread(() -> {
int t=count.incrementAndGet();
System.out.println(t+" 线程名:" + Thread.currentThread().getName() + " running ------");
}));
}
executor.shutdown();
}
}
executor.execute()提交任务执行,由于会抛出RuntimeException,如果没有try catch处理异常信息的话,会中断调用者的处理流程,后续任务得不到执行。

RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
在控制台可以看到,会显示main is running, 体现出调用线程也在处理任务。

RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
在控制台可以看到,实际被执行的任务没有100条,其它未被执行的任务被直接抛弃了。

RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();
在控制台可以看到,大量的任务被丢弃不能被执行。

四种拒绝策略是独立无关的处理策略,使用何种拒绝策略执行线程,需要结合实际业务。
通常实际开发中,我们使用ExecutorService,而它的默认拒绝策略是AbortPolicy
