在项目中使用AsyncTask过程中,出现过RejectedExecutionException这个异常,经过查看源码,发现在构造ThreadPoolExecutor时,ThreadPoolExecutor内部默认的RejectedExecutionHandler是AbortPolicy来实现的,AbortPolicy见名知义就是中断执行的策略既是抛出RuntimeException。在ThreadPoolExecutor内部有多种RejectedExecutionHandler的实现,包括:
AbortPolicy: 实现rejectdException方法的就是 throw RejectedExecutionException。 这也就是android上碰到的异常。
public static class AbortPolicy implements RejectedExecutionHandler {
/**
* Creates an {@code AbortPolicy}.
*/
public AbortPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
CallerRunsPolicy:从rejectdException的实现来看,直接调用Runnable#run()方法,不会扔出异常,而是让任务继续执行。
public static class CallerRunsPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code CallerRunsPolicy}.
*/
public CallerRunsPolicy() { }
/**
* Executes task r in the caller's thread, unless the executor
* has been shut down, in which case the task is discarded.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}
DiscardPolicy:rejectdException方法是一个空的实现,意思是忽略这个任务,此任务将不被执行
/**
* A handler for rejected tasks that silently discards the
* rejected task.
*/
public static class DiscardPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code DiscardPolicy}.
*/
public DiscardPolicy() { }
/**
* Does nothing, which has the effect of discarding task r.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}
DiscardOldestPlicy:rejectdException方法实现了将上一个任务移除,转而执行当前最新的这个任务。
/**
* A handler for rejected tasks that discards the oldest unhandled
* request and then retries {@code execute}, unless the executor
* is shut down, in which case the task is discarded.
*/
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code DiscardOldestPolicy} for the given executor.
*/
public DiscardOldestPolicy() { }
/**
* Obtains and ignores the next task that the executor
* would otherwise execute, if one is immediately available,
* and then retries execution of task r, unless the executor
* is shut down, in which case task r is instead discarded.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
}
根据上面的这些策略,我们可以根据我们的需求来设置不同的reject策略。如果上面都不能满足我们的需求,我们可以自己实现RejectedExecutionHandler。 那么我们如何设置AsyncTask的reject策略呢?
请参考以下代码:
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) AsyncTask.THREAD_POOL_EXECUTOR;
threadPoolExecutor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r,ThreadPoolExecutor executor) {
... //实现你的策略
}
});