在4种常见的线程池创建方式这篇文章里,通过查看源码发现,线程池的创建底层都是通过下面这个方法实现的,这个方法里有七个参数,也是面试中常常问到的知识点。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> 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.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
这个方法的七个参数都是什么意义呢?
- corePoolSize:常驻核心线程数,也就是说这是线程池中始终存活的线程,不会被销毁,除非关闭线程池。
- maximumPoolSize:最大线程数,线程池中最多能存活的线程数。
- keepAliveTime:空闲线程存活时间,配合下一个参数unit(空闲线程存活时间单位)使用。假如keepAliveTime=5L(注意:类型为long),unit = TimeUnit.SECONDS,则某个线程在5s时间里没有处理任何请求,将会被线程池销毁,当然是在线程池中线程数大于常驻核心线程数的情况下。
- unit:空闲线程存活时间的单位,如TimeUnit.SECONDS、TimeUnit.MILLISECONDS等。
- workQueue:工作队列(阻塞队列),简单来说,队列的容量决定了能有多少请求被阻塞队列接受。线程池达到最大线程数在处理请求,接下来的请求就会被放入阻塞队列等待处理。
- threadFactory:线程工厂,一般使用默认Executors.defaultThreadFactory()即可。
- handler:线程池的拒绝策略。当等待队列已经满了,再也塞不下新的任务,同时,线程池也达到max线程了,无法为新任务服务,这时,我们需要拒绝策略机制合理的处理这个问题。
关于最后一个拒绝策略的详细内容,可以看我的另一篇文章