1. 构造函数
- corePoolSize:池里维持的最小线程数,即使它们是空闲线程,也不会进行销毁
- maximumPoolSize:最大线程数
- keepAliveTime:当池里的线程数量超过了corePoolSize时,如果额外线程在keepAliveTime时间段内都未执行新任务,将被销毁
- 核心线程和额外线程是明确区分的,核心线程一般不会被销毁
- unit:keepAliveTime的时间单位
- workQueue:存放被执行任务的工作队列,只接受被提交的Runnable接口类
- threadFactory:线程工厂,专门生产新线程
- handler:当任务执行被阻塞时,用它来处理,默认是“拒绝执行处理器”,其会抛出一个 RejectedExecutionException
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;
}
2. 实现 ExecutorService 接口的 submit()方法
ThreadPoolExecutor 没有重写 submit(),被调用的是其父类 AbstractExecutorService 实现的 submit(),查看 AbstractExecutorService
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
//将 Runnable 封装成一个 RunnableFuture,对于 Runnable 意义不大,其主要针对 Callable
RunnableFuture<Void> ftask = newTaskFor(task, null);
//执行任务,由子类 ThreadPoolExecutor 实现
execute(ftask);
//返回 Future 接口,可返回最终计算结果,对于 Runnable 意义不大,其主要针对 Callable
return ftask;
}
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
查看 ThreadPoolExecutor 的 execute(Runnable command) 方法
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
//获取线程池状态值,其包含两个核心属性(方便同时对两个值的原子操作,底层采用了 CAS 而非锁)
//1.workerCount,有效线程数(代表那些已启动但不准停止的线程数量,与实际线程数可能不符)
//2.runState,主要用于线程池生命周期的控制
int c = ctl.get();
//如果有效线程数少于corePoolSize,创建一个Worker(包含一个新的核心线程)
if (workerCountOf(c) < corePoolSize) {
//如果创建成功,将command作为首次任务,因此不需要任务入队,可立即返回
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);
//如果有效线程数为0,创建一个Worker(包含一个新的额外线程),其不存在首次任务,故只能从工作队列中依次取任务
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
//当然,如果有效线程数不为0,不用管它,等待现有的空闲线程从工作队列中依次取任务即可
}
//(为了缓冲任务过多、队列已满)尝试创建一个Worker(包含一个新的额外线程),将command作为首次任务
else if (!addWorker(command, false))
//一旦创建失败了,意味着线程池已停工或饱和,直接拒绝
reject(command);
}
可以看到,核心的几个调用分别是① addWorker(command, true) 创建一个核心线程(一般不会被销毁),首次执行command,后正常运行;② addWorker(null, false) 创建一个额外线程,从队列中依次取任务;③ addWorker(command, false) 创建一个额外线程,首次执行command,后正常运行
查看源码 ThreadPoolExecutor 的 addWorker(Runnable firstTask, boolean core)
private boolean addWorker(Runnable firstTask, boolean core) {
//在环境允许时,将有效线程数+1(使用CAS原语保证同步,性能高于锁)
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
//一旦线程数成功+1,开始创建新线程
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
//此处构造很关键,其内部创建了一个标准的工作线程:一旦启动,可以不断地从队列中取出任务
w = new Worker(firstTask);
final Thread t = w.thread;
//检查线程是否被创建
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
//使用锁同步,将新线程加入池中(池的类型是HashSet,本身是非线程安全的)
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;
}
}
} finally {
//如果新线程产生各种失败,回滚整个流程:从池中删除它、线程数-1、尝试终止线程池
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
工作线程所运行的非常核心的run()由Worker类来实现,查看ThreadPoolExecutor.Worker源码
//Worker构造函数
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
//使用工厂类来新建一个工作线程
this.thread = getThreadFactory().newThread(this);
}
//传递给工作线程的run()方法
public void run() {
runWorker(this);
}
final void runWorker(Worker w) {
//注意,当前线程为工作线程,而非主线程
Thread wt = Thread.currentThread();
//设置首次任务
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
//获得首次任务,或从工作队列中获取最旧的任务(FIFO队列)
//由于是阻塞式的生产者/消费者队列,当缺少任务时,当前线程等待并挂起
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 {
//执行任务(队列只接受Runnable接口的任务)
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();
}
}
//当线程数超过了最大值、或线程池停止、或线程超时,则getTask()返回null,代码到达此处
completedAbruptly = false;
} finally {
//根据运行异常或线程池配置问题(例如最大数量、超时),选择性地进行线程销毁处理
processWorkerExit(w, completedAbruptly);
}
}