线程池执行Callable任务
ThreadPoolExecutor的父类AbstractExecutorService中的submit()方法可以执行实现Callable接口的任务,同时可以在Future中获取任务的返回值。而实现Callable接口的任务是被包装成FutureTask任务来执行的。
// 执行Callable任务,可以获取任务返回值
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
// 将Callable任务包装成FutureTask任务
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
FutureTask结构
FutureTask实现了Runnable接口和Future接口,它可以由线程池的submit()方法执行,并且可以返回结果,而且任务本身也有不同的状态。
FutureTask的几种状态
private volatile int state;
private static final int NEW = 0; // 新建一个任务
private static final int COMPLETING = 1; // 任务正在执行
private static final int NORMAL = 2; // 任务正常结束
private static final int EXCEPTIONAL = 3; // 任务执行异常
private static final int CANCELLED = 4; // 任务被取消
private static final int INTERRUPTING = 5; // 正在中断任务
private static final int INTERRUPTED = 6; // 任务已被中断
FutureTask的字段和构造方法
// 保存FutureTask封装的Callable任务
private Callable<V> callable;
// 保存Callable当中call方法返回的结果
private Object outcome;
// 正在执行call方法的线程
private volatile Thread runner;
// 保存被get方法挂起的线程,一个单向链表
private volatile WaitNode waiters;
static final class WaitNode {
volatile Thread thread; // 被挂起的线程
volatile WaitNode next; // 下一个节点
WaitNode() { thread = Thread.currentThread(); }
}
// 构造方法
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
// 任务初始为NEW状态
this.state = NEW;
}
FutureTask执行任务
FutureTask实现了Runnable接口,而在submit()方法中任务被封装后是由execute()方法执行的,所以线程池最终执行的还是run()方法。
public void run() {
// 1. 线程为初始状态,且可以成功设置当前执行run()方法的线程,则向下继续执行
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
// 2. 表示call()方法是否正常执行完成
boolean ran;
try {
// 3. 任务正常执行完成
result = c.call();
ran = true;
} catch (Throwable ex) {
// 4. 任务执行有异常
result = null;
ran = false;
setException(ex);
}
// 5. 如果正常执行,则保存call()方法返回的结果
if (ran)
set(result);
}
} finally {
// 置空当前执行run()方法的线程
runner = null;
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
setException()方法保存任务执行过程中的异常,set()方法保存任务正常执行完之后的返回结果
protected void set(V v) {
// 将New状态切换为Completing状态
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
// 保存结果到outcom中
outcome = v;
// 将状态设置为Normal状态
UNSAFE.putOrderedInt(this, stateOffset, NORMAL);
// 用于唤醒get方法中等阻塞的线程
finishCompletion();
}
}
protected void setException(Throwable t) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
// 将异常保存在返回结果中
outcome = t;
UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL);
finishCompletion();
}
}
finishCompletion()方法主要是唤醒waiters中被挂起的线程
private void finishCompletion() {
// 1. 遍历所有被挂起的线程
for (WaitNode q; (q = waiters) != null;) {
// 2. 将挂在waiters置null,挂起的线程保留在q中
if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {
for (;;) {
Thread t = q.thread;
if (t != null) {
q.thread = null;
// 3. 唤醒线程
LockSupport.unpark(t);
}
// 4. 获取下一个节点
WaitNode next = q.next;
if (next == null)
break;
q.next = null;
q = next;
}
break;
}
}
done();
callable = null; // to reduce footprint
}
FutureTask获取结果
get()方法可以从任务返回的结果中阻塞获取结果,支持无限等待和有限等待两种方式
public V get() throws InterruptedException, ExecutionException {
int s = state;
// 任务为新建和正在执行时,先挂起
if (s <= COMPLETING)
s = awaitDone(false, 0L);
// 被唤醒后,返回结果
return report(s);
}
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
if (unit == null)
throw new NullPointerException();
int s = state;
// 任务为未完成,则超时等待,如果超时后仍未完成,抛出异常
if (s <= COMPLETING &&
(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
throw new TimeoutException();
return report(s);
}
awaitDone()可以将任务挂起,并将挂起的任务加到waiters中
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
// 1. timed表示是否超时阻塞,nanos表示阻塞时间
final long deadline = timed ? System.nanoTime() + nanos : 0L;
WaitNode q = null;
boolean queued = false;
// (1)任务中断抛出异常;(2)任务结束返回;(3)等待结束返回
for (;;) {
// 2. 如果线程被中断,则从等待队列中移除
if (Thread.interrupted()) {
removeWaiter(q);
throw new InterruptedException();
}
// 3. 任务被执行完,绑定的thread置null(完成,异常,取消,异常)
int s = state;
if (s > COMPLETING) {
if (q != null)
q.thread = null;
return s;
}
// 4. 任务正在执行,则让出CPU
else if (s == COMPLETING)
Thread.yield();
// 5. 任务为新建,则创建新的WaitNode
else if (q == null)
q = new WaitNode();
// 6. WaitNode未入队列,则加入队列头部
else if (!queued)
queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
q.next = waiters, q);
else if (timed) {
nanos = deadline - System.nanoTime();
// 7. 如果等待结束,直接返回
if (nanos <= 0L) {
removeWaiter(q);
return state;
}
// 8. 超时等待
LockSupport.parkNanos(this, nanos);
}
else
// 9. 无限等待
LockSupport.park(this);
}
}
report()方法返回任务的计算结果
private V report(int s) throws ExecutionException {
// 返回outcome保存的结果
Object x = outcome;
if (s == NORMAL)
return (V)x;
if (s >= CANCELLED)
throw new CancellationException();
// 任务执行出现异常,返回任务的异常结果
throw new ExecutionException((Throwable)x);
}
FutureTask取消任务
cancel方法可以取消FutureTask的执行过程
// MayInterruptIfRunning表示可以在线程执行的时候中断
public boolean cancel(boolean mayInterruptIfRunning) {
// 只有任务为NEW,且能将NEW状态变为中断或取消才会向下执行,否则返回false
// 无法取消正在执行的任务
if (!(state == NEW &&
UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
try {
if (mayInterruptIfRunning) {
try {
// 正在执行任务的线程
Thread t = runner;
if (t != null)
// 中断改线程
t.interrupt();
} finally {
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
}
}
} finally {
// 唤醒阻塞的线程
finishCompletion();
}
return true;
}