线程池(ThreadPoolExecutor)的七大参数

101 阅读3分钟
/**
 * Creates a new {@code ThreadPoolExecutor} with the given initial
 * parameters.
 *
 * @param corePoolSize the number of threads to keep in the pool, even
 *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
 * @param maximumPoolSize the maximum number of threads to allow in the
 *        pool
 * @param keepAliveTime when the number of threads is greater than
 *        the core, this is the maximum time that excess idle threads
 *        will wait for new tasks before terminating.
 * @param unit the time unit for the {@code keepAliveTime} argument
 * @param workQueue the queue to use for holding tasks before they are
 *        executed.  This queue will hold only the {@code Runnable}
 *        tasks submitted by the {@code execute} method.
 * @param threadFactory the factory to use when the executor
 *        creates a new thread
 * @param handler the handler to use when execution is blocked
 *        because the thread bounds and queue capacities are reached
 * @throws IllegalArgumentException if one of the following holds:<br>
 *         {@code corePoolSize < 0}<br>
 *         {@code keepAliveTime < 0}<br>
 *         {@code maximumPoolSize <= 0}<br>
 *         {@code maximumPoolSize < corePoolSize}
 * @throws NullPointerException if {@code workQueue}
 *         or {@code threadFactory} or {@code handler} is null
 */
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)

核心线程数 corePoolSize

线程池中会维护一个最小的线程数量, 即使这些线程处于空闲状态, 他们也不会被销毁, 除非设置了allowCoreThreadTimeOut。
根据程序是CPU密集型还是IO密集型一般分两种计算方式
CPU密集型:CPU核心数+ 1
IO密集型:2*CPU核心数+1

最大线程数 maximumPoolSize

池中允许的最大线程数,当线程数量超出最大线程数时,超出的任务将放到工作队列中

空闲线程存活时间 keepAliveTime

当线程数大于核心线程数时,空闲的线程在存活时间内没有新任务接收,空闲的线程会被销毁

时间单位 unit

keepAliveTime的时间单位

工作队列 workQueue

在任务执行之前用于保存任务的队列;一共4中工作队列

  1. ArrayBlockingQueue
    基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略
  2. LinkedBlockingQuene
    基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而基本不会去创建新线程直到maxPoolSize(很难达到Interger.MAX这个数),因此使用该工作队列时,参数maxPoolSize其实是不起作用的。
  3. SynchronousQuene
    一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。
  4. PriorityBlockingQueue
    具有优先级的无界阻塞队列,优先级通过参数Comparator实现

创建线程工程 threadFactory

创建新线程时使用的工程,一般是默认工厂 DefaultThreadFactory

拒绝策略 handler

当最大线程数和工作队列都满了之后再有新任务进来时执行的拒绝策略;一共有4中拒绝策略

  1. CallerRunsPolicy
    该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。
  2. AbortPolic(默认策略)
    该策略下,直接丢弃任务,并抛出RejectedExecutionException异常。
  3. DiscardPolicy
    该策略下,直接丢弃任务,什么都不做。
  4. DiscardOldestPolicy
    该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列