当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize时,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:
- CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
- AbortPolicy(默认策略):丢弃任务并抛出RejectedExecutionException异常
- DiscardPolicy:丢弃任务,但是不抛出异常
- DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务
拒绝策略需要实现RejectedExecutionHandler接口:
public interface RejectedExecutionHandler {
/**
* @param r 请求执行的可运行任务
* @param executor 试图执行此任务的执行程序
* @throws RejectedExecutionException 如果没有拒绝策略,则抛出该异常
*/
void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}
四种策略的源码:
/**
* 由调用线程(提交任务的线程)处理该任务
*/
public static class CallerRunsPolicy implements RejectedExecutionHandler {
public CallerRunsPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}
/**
* 丢弃任务并抛出RejectedExecutionException异常
*/
public static class AbortPolicy implements RejectedExecutionHandler {
public AbortPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
/**
* 丢弃任务,但是不抛出异常
*/
public static class DiscardPolicy implements RejectedExecutionHandler {
public DiscardPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}
/**
* 丢弃队列最前面的任务,然后重新提交被拒绝的任务
*/
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
public DiscardOldestPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
}
如果有兴趣了解更多相关内容,欢迎来我的个人网站看看:耶瞳空间