JDK版本:1.7.0_45。本文尝试分析ThreadPoolExecutor的构造方法的参数的作用,然后再分析主要逻辑。
一、构造方法及其参数
ThreadPoolExecutor位于java.util.concurrent包,有4个带参数的构造方法。最终被调用的构造方法如下。其他构造方法只是提供了默认的ThreadFactory或者RejectedExecutionHandler作为参数。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
构造方法参数解析:
1. int corePoolSize
此参数字面上的意思是核心线程的数量。在public void execute(Runnable command)方法中,有以下几行代码:
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
}
其中workerCountOf(c)方法返回的是当前正在运行的线程数,addWorker(command,true)方法的功能则是启动一个新的线程以执行command。
可见,当有新任务来到,当前运行的线程数少于corePoolSize的时候,ThreadPoolExecutor二话不说就启动一个新的线程来执行这个任务。
2.int maximumPoolSize
最大可运行的线程数量。 在addWorker方法中:
private boolean addWorker(Runnable firstTask, boolean core) {
...
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
...
...
}
addWorker的功能是创建新的线程并执行。
从上面的代码可见,当当前运行的线程数量大于等于maximumPoolSize时,ThreadPoolExecutor将不会再创建新的线程。
3.long keepAliveTime
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
...
int wc = workerCountOf(c);
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
...
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
...
}
}
线程池中的线程运行完上一个任务之后,将会通过getTask方法获取下一个任务来执行。即从构造方法中的BlockingQueue<Runnable> workQueue参数--阻塞队列中获取。
从上面的代码中可知,当timed为true的时候,keepAliveTime才起作用。而timed在两种情况下才为true:
1.当前运行的线程数量大于核心线程的数量。2.allowCoreThreadTimeOut为true(此变量可通过public void allowCoreThreadTimeOut(boolean value)方法设置),即设置核心线程也受等待时长限制。
所以keepAliveTime的作用是,