线程池的拒绝策略

发布于:2023-12-04 ⋅ 阅读:(94) ⋅ 点赞:(0)

线程池的拒绝策略

若在线程池当中的核心线程数已被用完且阻塞队列已排满,则此时线程池的线程资源已耗尽,线程池没有足够的线程资源执行新的任务。

所以为了保证操作系统的安全性,线程池将通过拒绝策略来处理新添加的线程任务。

JDK 中内置的拒绝策略有 AbortPolicy,CallerRunsPolicy、DiscardOldestPolicy、DiscardPolicy 这4种,默认的拒绝策略在 ThreadPoolExecutor 中作为内部类来进行提供的,在默认的拒绝策略都不能满足应用的需求时,也可以自定义拒绝策略。

AbortPolicy拒绝策略:

该策略会直接抛出异常,阻止系统正常工作。

jdk源码:

    /**
     * A handler for rejected tasks that throws a
     * {@code RejectedExecutionException}.
     */
    public static class AbortPolicy implements RejectedExecutionHandler {
        /**
         * Creates an {@code AbortPolicy}.
         */
        public AbortPolicy() { }
        /**
         * Always throws RejectedExecutionException.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         * @throws RejectedExecutionException always
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
    }

CallerRunsPolicy拒绝策略:

如果线程池的线程数量达到上限,该策略会把任务队列中的任务放在调用者线程(如main函数)当中运行。

jdk源码:

    /**
     * A handler for rejected tasks that runs the rejected task
     * directly in the calling thread of the {@code execute} method,
     * unless the executor has been shut down, in which case the task
     * is discarded.
     */
    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();
            }
        }
    }

DiscardOldestPolicy拒绝策略:

该策略将移除最早的一个请求,也就是即将被执 行的任务,然后并尝试再次提交当前的任务。

jdk源码:

    /**
     * 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);
            }
        }
    }

DiscardPolicy拒绝策略:

丢弃当前线程任务而不做任何处理。如果系统允许在资源不足的情况下丢弃部分任务,则这将是保障系统安全,稳定的一种很好的方案。

jdk源码:

    /**
     * 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) {
        }
    }

以上4种拒绝策略均是实现的 RejectedExecutionHandler 接口,来实现拒绝策略,若无法满足实际需要,则用户就可以自己自定义来实现拒绝策略。

本文含有隐藏内容,请 开通VIP 后查看