java线程池ThreadPoolExecutor的拒绝策略RejectedExecutionHandler

近期在面试时问题时问到了 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值