1、任务提交
// 创建线程池提交任务
ExecutorService executorService = Executors.newFixedThreadPool(1);
for (int i=0;i<3;i++){
// 提交任务,由AbstractExecutorService#submit实现
executorService.submit(()->{
System.out.println(Thread.currentThread().getName());
});
}
Thread.sleep(500);
executorService.shutdown();
//=========================上述逻辑执行流程代码分析===================
//AbstractExecutorService#submit,有三个重载方法
// 提交Runnable类型的任务,不带有返回值
public Future<?> submit(Runnable task)
// 提交带有返回值的Runnable,其中返回值为null(要想从线程池中获取执行结果,需要提交Callable类型任务)
public <T> Future<T> submit(Runnable task, T result)
// 提交Callable类型的任务,自带返回结果
public <T> Future<T> submit(Callable<T> task)
// 以Runnable类型任务为例
public Future<?> submit(Runnable task) {
// 入口检查,防止提交null
if (task == null) throw new NullPointerException();
// 类型转换,统一将提交的任务转换成RunnableFuture,其实是转换成FutureTask(FutureTask是RunnableFuture的一种实现)
RunnableFuture<Void> ftask = newTaskFor(task, null);
// 任务提交的真正入口
execute(ftask);
return ftask;
}
//AbstractExecutorService#newTaskFor
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
//FutureTask#构造
public FutureTask(Runnable runnable, V result) {
// 使用适配器模式,将Runnable类型任务转成Callable类型,底层依赖于RunnableAdapter
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
// ThreadPoolExecutor#execute
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
// 获取线程池状态
int c = ctl.get();
// 线程池线程个数小于核心线程数,该情况下直接将当前任务放入线程池执行
if (workerCountOf(c) < corePoolSize) {
// 条件成立,说明放入线程池成功(会启动一个新线程执行该任务)
if (addWorker(command, true))
return;
c = ctl.get();
}
// 执行到这,前提条件有两个 1、核心线程数已到,需要排队 2、线程池放入失败,执行入队
// 入队失败后执行在构建线程池对象设定的拒绝策略
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);
}
// 添加worker(worker是线程池中之行任务的线程,循环的从队列中获取任务执行),对用的逻辑是在线程池中开启线程
private boolean addWorker(Runnable firstTask, boolean core) {
// 这些是一些条件判断,直接略过
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
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
// 将提交的任务包装成worker(FutureTask实现了RunnableFuture,RunnableFuture实现了Runnable,故可以用Runnable表示提交的任务)
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// 获取线程池运行状态
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) {
// 启动worker执行任务,worker开始运行,执行worker的run方法
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
// Worker#run ,线程池中任务处理
public void run() {
runWorker(this);
}
2、任务执行
// ThreadPoolExecutor#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 {
// 循环从任务队列中获取任务,任务来源有两种。1、任务提交的原始任务,此时线程池未满,直接构建线程执行 2、等待队列中获取 。队列获取任务是阻塞操作,队列为空时,线程会阻塞等待任务提交
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
// 任务最终执行处。通过submit方法向线程池中提交的任务都是被转换成FutureTask类型,并重写了run方法。故此处执行的是FutureTask中重写的run方法
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();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
// FutureTask#run
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
// 提交的任务,不管是Runnable还是Callable都会被转换为Callable
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
// 标记任务是否完成
boolean ran;
try {
// 调用用户自定义逻辑
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
// 异常,使用get方法会得到该异常信息
setException(ex);
}
if (ran)
// 正常执行,结果设置
set(result);
}
} finally {
runner = null;
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
// FutureTask#set正常结果设置
protected void set(V v) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
// 线程池执行结果
outcome = v;
UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
// 任务执行完成之后的处理,用于唤醒线程池任务还没执行完成之前调用get方法获取结果导致阻塞的线程。这些被阻塞的线程会被放入阻塞队列
finishCompletion();
}
}
// FutureTask#setException 同上,只是是异常
protected void setException(Throwable t) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = t;
UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
finishCompletion();
}
}
// FutureTask# finishCompletion
private void finishCompletion() {
// assert state > COMPLETING;
// 遍历阻塞队列
for (WaitNode q; (q = waiters) != null;) {
if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {
for (;;) {
Thread t = q.thread;
// 阻塞队列中有值,表示有线程在调用get方法时被阻塞。现在结果已出,需要唤醒被阻塞的线程
if (t != null) {
q.thread = null;
LockSupport.unpark(t);
}
WaitNode next = q.next;
if (next == null)
break;
q.next = null; // unlink to help gc
q = next;
}
break;
}
}
// 提供的扩展点。在任务执行完成之后自定义逻辑
done();
callable = null; // to reduce footprint
}
3、获取结果
// FutureTask#get 获取向线程池提交任务的执行结果
public V get() throws InterruptedException, ExecutionException {
// 获取当前任务执行的状态
int s = state;
// 条件成立表示任务正在执行中,当前获取结果线程需要放入等待队列并阻塞
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}
// FutureTask#awaitDone等待执行结果
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
// get操作如果指定超时则使用,否则为0,表示不需要超时逻辑
final long deadline = timed ? System.nanoTime() + nanos : 0L;
WaitNode q = null;
boolean queued = false;
for (;;) {
// 任务结果获取过程中,用户执行了取消逻辑,需要将该线程从阻塞队列中删除
if (Thread.interrupted()) {
removeWaiter(q);
throw new InterruptedException();
}
// 任务执行状态
int s = state;
// 条件成立,表示任务执行完毕,可以获取结果,之后跳出循环
if (s > COMPLETING) {
if (q != null)
q.thread = null;
return s;
}
// 条件成立,出现的可能是,任务已经完成,但是还没有将执行结果赋值给outcome。这种情况下不需要阻塞
else if (s == COMPLETING) // cannot time out yet
Thread.yield();
// 这种情况是第一次进入排队逻辑。需要将当前调用get方法的线程封装成WaitNode。在第二次进入时,如果任务还没有执行完成,需要 入队
else if (q == null)
q = new WaitNode();
else if (!queued)
queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
q.next = waiters, q);
// 下面的逻辑是park逻辑。被唤醒后表示结果已具备,获取执行结果然后跳出循环,完成取数操作
else if (timed) {
nanos = deadline - System.nanoTime();
if (nanos <= 0L) {
removeWaiter(q);
return state;
}
// park当前线程(带有超时)
LockSupport.parkNanos(this, nanos);
}
else
// park当前线程
LockSupport.park(this);
}
}
4、流程分析图