ThreadPoolExecutor的Reject策略
今天我们专门聊聊ThreadPoolExecutor的拒绝策略
入口
我们还是需要回到最开始的execute方法:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
我们可以看到线程池会在corePoolSize的线程池大小上尝试添加失败(addWorker(command, true))之后再次进行在maximumPoolSize大小上尝试添加(addWorker(null, false))。如果都失败了就会调用reject(command)。进行拒绝策略的处理。
final void reject(Runnable command) {
handler.rejectedExecution(command, this);
}
reject会调用接口RejectedExecutionHandler的rejectedExecution方法.而RejectedExecutionHandler在ThreadPoolExecutor中有如下几个默认实现(都是内部类):
- AbortPolicy: 抛出一个RejectedExecutionException异常,然后抛弃任务.
- CallerRunsPolicy: 如果线程池没有关闭直接在线程池中执行被拒绝的任务,否则任务会被丢弃。
- DiscardPolicy: 直接丢弃被拒绝的任务,不做任何事.
- DiscardOldestPolicy: 如果线程池没有关闭,则将队列(workQueue)的队头任务(等待最久的任务)抛弃,然后尝试将被拒绝的任务再次添加到队列中。如果线程池已经关闭则直接丢弃任务
ThreadPoolExecutor的默认实现是AbortPolicy。