ThreadPoolExecutor

使用的常见 Executor 是 ThreadPoolExecutor,它负责线程处理。如果还有更多工作要做,你可以配置执行程序在没有太多操作时必须维护的最小线程数(它称为核心大小)和池可以增长的最大线程大小。一旦工作负载下降,Pool 会再次缓慢减少线程计数,直到达到最小值。

ThreadPoolExecutor pool = new ThreadPoolExecutor(
    1,                                     // keep at least one thread ready, 
                                           // even if no Runnables are executed
    5,                                     // at most five Runnables/Threads
                                           // executed in parallel
    1, TimeUnit.MINUTES,                   // idle Threads terminated after one
                                           // minute, when min Pool size exceeded
    new ArrayBlockingQueue<Runnable>(10)); // outstanding Runnables are kept here

pool.execute(new Runnable() {
    @Override public void run() {
        //code to run
    }
});

注意如果使用无界队列配置 ThreadPoolExecutor ,则线程计数不会超过 corePoolSize,因为只有队列已满时才会创建新线程:

ThreadPoolExecutor 包含所有参数:

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, 
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)

来自 JavaDoc

如果有多个 corePoolSize 但运行的 maximumPoolSize 线程少于 maximumPoolSize,则只有在队列已满时才会创建新线程。

好处:

  1. 可以控制 BlockingQueue 大小,并且可以避免内存不足的情况。有限的有界队列大小不会降低应用程序性能。

  2. 你可以使用现有或创建新的拒绝处理程序策略。

    1. 在默认的 ThreadPoolExecutor.AbortPolicy 中,处理程序在拒绝时抛出运行时 RejectedExecutionException。

    2. ThreadPoolExecutor.CallerRunsPolicy 中,调用 execute 本身的线程运行任务。这提供了一种简单的反馈控制机制,可以降低新任务的提交速度。

    3. ThreadPoolExecutor.DiscardPolicy 中,简单地删除了无法执行的任务。

    4. ThreadPoolExecutor.DiscardOldestPolicy 中,如果执行程序未关闭,则会删除工作队列头部的任务,然后重试执行(可能会再次失败,导致重复执行)。

  3. 可以配置自定义 ThreadFactory,这很有用:

    1. 设置更具描述性的线程名称
    2. 设置线程守护程序状态
    3. 设置线程优先级

以下是如何使用 ThreadPoolExecutor 的示例