线程池会保持coorPoolSize个线程一致存活,等待submit或者execute提交任务来执行,这个机制是怎么保证的呢?
这其实是归因于ThreadPool
中的Worker
的run
方法,我们来看一看
1.添加Worker
当我们执行execute
或者submit
提交一个任务之后,如果这时候没有Worker
存在会添加一个Worker
,精简后的方法如下
private boolean addWorker(Runnable firstTask, boolean core) {
try {
w = new Worker(firstTask);
final Thread t = w.thread;
//...............此处省略一部分代码
workers.add(w);
//...............此处省略一部分代码
workerAdded = true;
//...............此处省略一部分代码
if (workerAdded) {
t.start();
workerStarted = true;
}
}
return workerStarted;
}
可见 addWorker
方法如果具备添加一个Worker的条件,就会添加一个Worker
实例 ,并调用Worker
中的线程t
的start
方法.
2. Worker的执行
那么我们要看一下Worker
中这个线程t
是个什么,它的Run方法又执行了什么
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable{
final Thread thread;
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
}
可以看出Worker
实现了Runnable
接口,
Worker
的成员变量thread在构造方法中初始化,传入了this.所以t.start()
会执行Worker的run方法
我们看看它的run方法
/** Delegates main run loop to outer runWorker */
public void run() {
runWorker(this);
}
可以看到调用了runWorker,看看精简版的runWorker
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
task.run();
}
}
如果task不为空则调用task.run, 如果为空则通过getTask()
获取一个task, 如此往复循环,
那么,如果task为null 并且通过getTask()
获取到的也为null, 这个循环就结束了,
那么它如何保证线程池里一直有Worker线程存在等待执行.
关键就在于getTask()
方法能不能源源不断的提供不为null的task了
3. getTask
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// Are workers subject to culling?
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
从上面的代码可以看出,只要一些条件不成立,getTask()
方法就会不停的从workQueue里面取出来不为空的task返回,如果为空就继续循环.