ThreadPoolExecutor的两个核心集合:
一个是持有当前可用线程的集合HashSet
,
另一个是待执行的task的集合BlockingQueue
线程池之所以成为线程池是,我们在试图运行一个具体的task时,我们没有调用Thread.start()方法,而是通过worker线程对象来调用task中的run()方法。
注意start()会开启一个新的线程,而run()是运行在当前线程中的。
当我们调用ThreadPoolExecutor中的Execute方法时,线程池会对当前自身状态做出判断来决定是否创建新的worker来立即执行task,或者是将task放置在workQueue队列中。
Execute代码片段:
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
在addWorker方法中,我们创建了一个封装task的worker对象。Worker内部类是一个Runnable接口的实现,addWorker创建完worker后,会启动worker自身持有的thread属性的start()方法来允许worker的run()方法。
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
而Worker类中run()方法调用的是ThreadPoolExecutor的runWorker(Worker w)方法,通过不断的查看持有task的集合workQueue中是否还有未执行的task来复用当前的worker线程。
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
在runWorker(Worker w)方法的最后,调用了processWorkerExit()方法。
这个方法的Javadoc是:
* Performs cleanup and bookkeeping for a dying worker. Called
* only from worker threads. Unless completedAbruptly is set,
* assumes that workerCount has already been adjusted to account
* for exit. This method removes thread from worker set, and
* possibly terminates the pool or replaces the worker if either
* it exited due to user task exception or if fewer than
* corePoolSize workers are running or queue is non-empty but
* there are no workers.
其中将当前的worker()移除了workers集合,随之又创建一个idle的worker:
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
workers.remove(w); // 将worker移除
} finally {
mainLock.unlock();
}
tryTerminate();
int c = ctl.get();
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) {
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
addWorker(null, false); // 创建一个idle线程
}
那为什么要把原来的worker移走呢?
我暂时的理解是,因为worker执行完一个task后,它的状态为terminated,不可能再转变成了runnable,所以我们需要用一个idle的worker去替代它。
那么问题又来了,idle的worker在addWorker中又会被启动,如果它什么都不做,难道又会在绕进processWorkerExit()方法中被另一个idle的worker替代?
有待思考。