线程池执行策略

构造函数说明

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
//............
    }

构造参数说明。

corePoolSize:

表示核心线程数量。

maximumPoolSize:

表示线程池最大能够容纳同时执行的线程数,必须大于或等于 1。如果和 corePoolSize 相等即是固定大小线程池。

keepAliveTime:

表示线程池中的线程空闲时间,当空闲时间达到此值时,线程会被销毁直到剩下 corePoolSize 个线程。

unit:

用来指定 keepAliveTime 的时间单位,有 MILLISECONDS、SECONDS、MINUTES、HOURS 等。

workQueue:

等待队列,BlockingQueue 类型。当请求任务数大于 corePoolSize 时,任务将被缓存在此 BlockingQueue 中。
注意, 等待队列有三种类型:
①无界队列:比如LinkedBlockingQueue. 核心线程处理不了的task都会被放到队列中,非核心线程没机会执行task。当task过多,可能会导致oom。
②有界队列:比如ArrayBlockingQueue
③SynchronousQueue:没有容量, 不存储元素,task会直接交给非核心线程处理。

threadFactory:

线程工厂,线程池中使用它来创建线程,如果传入的是 null,则使用默认工厂类 DefaultThreadFactory。

handler:

执行拒绝策略的对象。当 workQueue 满了之后并且活动线程数大于 maximumPoolSize 的时候,线程池通过该策略处理请求。
来自 Android 34讲

执行策略

image.png

新来一个task

  1. 判断核心线程数是否已创建完
    比如核心线程数为5, 当前只创建了3个核心线程,那就再创建第4个,来执行新来的task。如果当前已创建了5个核心线程,就执行步骤2
    2.判断是否有空闲的核心线程
    比如5个核心线程只有3个在工作,其他2个处于空闲状态,则交给空闲的核心线程来执行task。如果5个核心线程都在工作,就执行步骤3
    3.判断阻塞队列还有没有空闲的位置放下新来的task
    如果阻塞队列有空位置,就放进队列等待执行。如果没有,就执行步骤4
    4.判断还能不能创建非核心线程来执行task
    假如最大线程数是10, 核心线程数是4,就意味着最多可以有4个核心线程和6个非核心线程。
    ①如果当前已经有4个核心线程和3个非核心线程了,那当前线程池的线程总数是7,小于最大线程数10,还可以再创建3个非核心线程。新来了task,那就创建一个非核心线程,来执行task。
    ②如果当前已经有4个核心线程和6个非核心线程,那就执行步骤5
    5.把task交给RejectedExecutionHandler#rejectedExecution
    RejectedExecutionHandler几个实现类,默认执行ThreadPoolExecutor.AbortPolicy,抛出RejectedExecutionException异常
    /**
     * 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());
        }
    }

你可能感兴趣的:(线程池执行策略)