1. execute的执行的重点
- poolSize < corePoolSize的时候,会创建线程
- 如果pollSize >= corePoolSize,会尝试放到队列里面,如果能放到队列里面,就直接返回
- 如果队列也放不下了,但是poolSize < maximumPoolSize,会执行addIfUnderMaximumPoolSize
- 注意这里是个for (;;) ,也就是说,如果会执行addIfUnderMaximumPoolSize最后return的runnable != command时候,会进入下一次循环
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
for (;;) {
if (runState != RUNNING) {
reject(command);
return;
}
if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))
return;
if (workQueue.offer(command))
return;
Runnable r = addIfUnderMaximumPoolSize(command);
if (r == command)
return;
if (r == null) {
reject(command);
return;
}
// else retry
}
}
2.线程池之所以是线程池
线程池之所以是线程池,是因为它可以使用少数几个线程来跑若干给runnable。 使之能工作的就是Worker这个内部类。
/**
* Main run loop
*/
public void run() {
try {
Runnable task = firstTask;
firstTask = null;
while (task != null || (task = getTask()) != null) {
runTask(task);
task = null; // unnecessary but can help GC
}
} catch(InterruptedException ie) {
// fall through
} finally {
workerDone(this);
}
}
Runnable getTask() throws InterruptedException {
for (;;) {
switch(runState) {
case RUNNING: {
if (poolSize <= corePoolSize) // untimed wait if core
return workQueue.take();
long timeout = keepAliveTime;
if (timeout <= 0) // die immediately for 0 timeout
return null;
Runnable r = workQueue.poll(timeout, TimeUnit.NANOSECONDS);
if (r != null)
return r;
if (poolSize > corePoolSize) // timed out
return null;
// else, after timeout, pool shrank so shouldn't die, so retry
break;
}
//省略其他状态
}
}
private void runTask(Runnable task) {
final ReentrantLock runLock = this.runLock;
runLock.lock();
try {
// Abort now if immediate cancel. Otherwise, we have
// committed to run this task.
if (runState == STOP)
return;
Thread.interrupted(); // clear interrupt status on entry
boolean ran = false;
beforeExecute(thread, task);
try {
task.run();
ran = true;
afterExecute(task, null);
++completedTasks;
} catch(RuntimeException ex) {
if (!ran)
afterExecute(task, ex);
// Else the exception occurred within
// afterExecute itself in which case we don't
// want to call it again.
throw ex;
}
} finally {
runLock.unlock();
}
}
- Worker是一个Runnable,看它的run函数,就是不停地从队列中取runnable,然后runTask(runnable)
- 我们可以使用corePoolSize数量的Worker来不停地运行queue中的runnable
- keepAliveTime,空闲的Worker等待队列的时间,如果poolSize < corePoolSize的情况下,就一直等,否则如果超时了,Worker的run就return了,线程就会被销毁。