近期在面试时问题时问到了 ThreadPoolExecutor 的拒绝策略 RejectedExecutionHandler 的实现 CallerRunsPolicy,之前没深入思考过,在此记录一下。
RejectedExecutionHandler 源码
package java.util.concurrent;
/**
* A handler for tasks that cannot be executed by a {@link ThreadPoolExecutor}.
*
* @since 1.5
* @author Doug Lea
*/
public interface RejectedExecutionHandler {
/**
* Method that may be invoked by a {@link ThreadPoolExecutor} when
* {@link ThreadPoolExecutor#execute execute} cannot accept a
* task. This may occur when no more threads or queue slots are
* available because their bounds would be exceeded, or upon
* shutdown of the Executor.
*
* In the absence of other alternatives, the method may throw
* an unchecked {@link RejectedExecutionException}, which will be
* propagated to the caller of {@code execute}.
*
* @param r the runnable task requested to be executed
* @param executor the executor attempting to execute this task
* @throws RejectedExecutionException if there is no remedy
*/
void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}
具体的实现类在 ThreadPoolExecutor 中,内置的拒绝策略如下
如果在使用 ThreadPoolExecutor 时未指定 RejectedExecutionHandler 参数,则使用默认的拒绝策略 AbortPolicy。可以看到源码是直接抛出异常。
顾名思义,针对提交的任务进行丢弃。看源码针对提交的任务不做处理,符合丢弃的思想。
针对提交的任务将未处理的最老的任务丢弃掉,即调用了 BlockingQueue#poll() 将队列头上的任务给移除掉,接下来将任务进行添加等待被执行。
看到名字的意思是调用者执行,看到源码的执行逻辑是直接调用 Runnable#run(),没有调用 Thread#start(),这样就不会通过操作系统单独创建线程来处理任务,对应的逻辑处理直接在当前调用 execute() 的线程上处理。
多线程的任务执行实际上通过 Thread#start() 来实现的,在调用 start() 后会进入 READY 状态,等待 cpu 调度执行,被调度后进入 RUNNING 状态,执行对应的 run() 中的逻辑。
通过 Thread#start() 触发的任务是异步执行的。
如果直接调用 Thread#run(),就是一个普通方法,执行是同步的。
在 ThreadPoolExecutor 中通过 ThreadFactory 来创建,如果未指定,默认实现类是 Executors#defaultThreadFactory(),创建的线程是用户线程,对应的线程类是 ThreadPoolExecutor 的内部类 Worker(继承了抽象类 AbstractQueuedSynchronizer 并且实现了接口 Runnable)。
在线程池中建议使用此策略,可以防止在执行过程中任务丢失的问题。
CallerRunsPolicy 和 DiscardOldestPolicy 的任务执行建立在线程池在没有结束的基础上,否则任务被丢弃。
之前自己写的文章
https://blog.csdn.net/zlpzlpzyd/article/details/124250907
https://blog.csdn.net/zlpzlpzyd/article/details/133500502
参考链接
https://blog.csdn.net/weixin_68105699/article/details/126474048