java线程池ThreadPoolExecutor的拒绝策略RejectedExecutionHandler

发布时间:2024年01月22日

近期在面试时问题时问到了?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.
     *
     * <p>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 中,内置的拒绝策略如下

AbortPolicy

如果在使用?ThreadPoolExecutor?时未指定 RejectedExecutionHandler 参数,则使用默认的拒绝策略?AbortPolicy。可以看到源码是直接抛出异常。

?

DiscardPolicy

顾名思义,针对提交的任务进行丢弃。看源码针对提交的任务不做处理,符合丢弃的思想。

DiscardOldestPolicy

针对提交的任务将未处理的最老的任务丢弃掉,即调用了 BlockingQueue#poll() 将队列头上的任务给移除掉,接下来将任务进行添加等待被执行。

CallerRunsPolicy

看到名字的意思是调用者执行,看到源码的执行逻辑是直接调用?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

文章来源:https://blog.csdn.net/zlpzlpzyd/article/details/135740830
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。