Java多线程高并发高级篇(三)--线程池核心中拒绝策略解密

阅读更多

在ThreadPoolExecutor的核心构造函数中,最后一个参数就是拒绝策略处理器。拒绝策略是等待任务队列已满,并且线程池处理不了任务时候,就需要一套处理机制,去解决这个问题(是抛弃还是怎么的)。

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

 JDK内置了4种拒绝策略,分别是AbortPolicy,CallerRunsPolicy,DiscardOldestPolicy,DiscardPolicy。

Java多线程高并发高级篇(三)--线程池核心中拒绝策略解密_第1张图片
 我们介绍下这4中策略:

1、AbortPolicy

该策略会直接抛出运行时异常,阻止系统继续执行,处理方式简单粗暴。我们看源码:

public static class AbortPolicy implements RejectedExecutionHandler {
        /**
         * Creates an 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();
        }
    }

 
Java多线程高并发高级篇(三)--线程池核心中拒绝策略解密_第2张图片
 

2、CallerRunsPolicy

只要线程池不关闭,该策略直接在调用者(Caller)线程中运行(Runs)当前被抛弃出来的任务。这么做的弊端是调用者线程(任务提交线程)的性能下降。看源码:

public static class CallerRunsPolicy implements RejectedExecutionHandler {
        /**
         * Creates a 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();
            }
        }
    }

 3、DiscardOldestPolicy

只要线程池不关闭,该策略将丢弃最老的一个任务(e.getQueue().poll())并且执行最新一个要执行的任务请求,看源码:

public static class DiscardOldestPolicy implements RejectedExecutionHandler {
        /**
         * Creates a 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);
            }
        }
    }

 

4、DiscardPolicy

该策略啥也不做,默默的丢弃任务(我从来没有来过。。。)

public static class DiscardPolicy implements RejectedExecutionHandler {
        /**
         * Creates a 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) {
        }
    }

 

  • Java多线程高并发高级篇(三)--线程池核心中拒绝策略解密_第3张图片
  • 大小: 5.5 KB
  • Java多线程高并发高级篇(三)--线程池核心中拒绝策略解密_第4张图片
  • 大小: 13.3 KB
  • 查看图片附件

你可能感兴趣的:(Java多线程高并发高级篇(三)--线程池核心中拒绝策略解密)