注:ThreadPoolExecutor 核心线程池创建器,Executors中的四种预定义线程池创建方式均是基于该创建器实现
我们以最后一个构造方法(参数最多的那个),对其参数进行解释:
首先来看它的构造方法
public ThreadPoolExecutor(int corePoolSize, // 1 int maximumPoolSize, // 2 long keepAliveTime, // 3 TimeUnit unit, // 4 BlockingQueue<Runnable> workQueue, // 5 ThreadFactory threadFactory, // 6 RejectedExecutionHandler handler ) { //7 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; }
可以看到该构造方法有一下几种参数
序号 | 参数名称 | 参数类型 | 参数含义 |
1 |
corePoolSize |
int |
核心线程池大小 |
2 |
maximumPoolSize |
int |
最大线程池大小 |
3 |
keepAliveTime |
long |
线程最大空闲时间 |
4 |
unit |
TimeUnit |
时间单位 |
5 |
workQueue |
BlockingQueue<Runnable> |
线程等待队列 |
6 |
threadFactory |
ThreadFactory |
线程创建工厂 |
7 |
handler |
RejectedExecutionHandler |
拒绝策略 |
各个参数解释
corePoolSize
核心线程池大小。在创建线程池之后,默认情况下线程池中并没有任何的线程,而是等待任务到来才创建线程去执行任务,当线程池中的线程数目达到 corePoolSize后,新来的任务将会被添加到线程等待队列(workQueue)中
PS:很多人不知道这个数该填多少合适,其实也不必特别纠结,根据实际情况填写就好,实在不知道,就按照阿里工程师的写法取下列值就好了:
int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
maximumPoolSize
线程池中的最大线程数。表示线程池中最多可以创建多少个线程,很多人以为它的作用是这样的:”当线程池中的任务数超过 corePoolSize 后,线程池会继续创建线程,直到线程池中的线程数小于maximumPoolSize“,其实这种理解是完全错误的。它真正的作用是:当线程池中的线程数等于 corePoolSize 并且 workQueue 已满,这时就要看当前线程数是否大于 maximumPoolSize,如果小于maximumPoolSize 定义的值,则会继续创建线程去执行任务, 否则将会调用去相应的任务拒绝策略(handler)来拒绝这个任务。另外超过 corePoolSize的线程被称做"Idle Thread", 这部分线程会有一个最大空闲存活时间(keepAliveTime),如果超过这个空闲存活时间还没有任务被分配,则会将这部分线程进行回收
keepAliveTime
超过 corePoolSize的线程被称做"Idle Thread", 这部分线程会有一个最大空闲存活时间(keepAliveTime),如果超过这个空闲存活时间还没有任务被分配,则会将这部分线程进行回收
unit
keepAliveTime的时间单位
workQueue
阻塞队列。如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到该队列当中,注意只要超过了 corePoolSize 就会把任务添加到该缓存队列,添加可能成功也可能不成功,如果成功的话就会等待空闲线程去执行该任务,若添加失败(一般是队列已满),就会根据当前线程池的状态决定如何处理该任务(若线程数 < maximumPoolSize 则新建线程;若线程数 >= maximumPoolSize,则会根据拒绝策略做具体处理)。
threadFactory
线程工厂。用来为线程池创建线程,当我们不指定线程工厂时,线程池内部会调用Executors.defaultThreadFactory()
创建默认的线程工厂,其后续创建的线程优先级都是Thread.NORM_PRIORITY
。如果我们指定线程工厂,我们可以对产生的线程进行一定的操作。
handler
拒绝执行策略。当线程池的缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:
ThreadPoolExecutor.AbortPolicy: // 丢弃任务并抛出RejectedExecutionException异常。 ThreadPoolExecutor.DiscardPolicy: // 也是丢弃任务,但是不抛出异常。 ThreadPoolExecutor.DiscardOldestPolicy: // 丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程) ThreadPoolExecutor.CallerRunsPolicy: // 由调用线程处理该任务