FutureTask代表了一个异步执行的任务。
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(2);
FutureTask task = new FutureTask(() -> 1);
executorService.submit(task);
System.out.println(task.get());
//task.cancel(true);
//task.isDone();
}
常用方法:
- isDone 任务是否完成
- get 无限期等待结果
- cancel 取消任务
成员变量
//当前任务的状态
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;
/** The underlying callable; nulled out after running */
private Callable<V> callable;
//get()方法返回的结果
private Object outcome; // non-volatile, protected by state reads/writes
/** The thread running the callable; CASed during run() */
private volatile Thread runner;
/** Treiber stack of waiting threads */
private volatile WaitNode waiters;
run方法
//由于 FutureTask 实现了 RunnableFuture, RunnableFuture继承了Runnable,
//而线程池只执行Runnable的run方法,所以run方法是FutureTask放入线程,执行的第一个方法
public void run() {
//状态必须是NEN新建状态,且成功的将其runner修改为当前线程,代表了FutureTask 就保留了当前正在执行他的线程,所以我们就可以通过runner对象,在cancel中中断线程
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
//执行体不为空,且当前状态为NEW状态,以最开始的示例为例,执行体为 () -> 1
if (c != null && state == NEW) {
V result;
boolean ran;
try {
//执行并获得结果
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
//执行失败,设置异常结果
ran = false;
setException(ex);
}
if (ran)//执行完成设置结果
set(result);
}
} finally {
// 执行完毕,不持有runner的引用,help GC
runner = null;
// 判断状态是否被中断,如果中断,调用handlePossibleCancellationInterrupt处理中断
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
setException
//当任务执行时发生了异常,那么调用该方法,将FutureTask变为异常完成状态。
//转换的时候会有一个中间状态COMPLETING。在框架设计或者源码编写的时候,只要涉及到高并发,
//大部分做状态转换时,会出现中间状态。
protected void setException(Throwable t) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = t;
//putOrderedInt不保证可见性,但是保证不会发生重排序,也即不会重排序到上一行代码中
UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
finishCompletion();
}
}
finishCompletion
//完成整个FutureTask的执行
private void finishCompletion() {
// assert state > COMPLETING;
for (WaitNode q; (q = waiters) != null;) {
//如果有别的线程等待当前任务完成,将他们唤醒
if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {
for (;;) {
Thread t = q.thread;
//等待线程不为空,调用LockSupport.unpark唤醒
if (t != null) {
q.thread = null;
LockSupport.unpark(t);
}
WaitNode next = q.next;
if (next == null)
break;
q.next = null; // 断开保留下一个任务的链 help gc
q = next;
}
break;
}
}
//此时所有等待任务完成的线程都被唤醒,回调子类的钩子函数
done();
callable = null; // to reduce footprint
}
set
//调用该函数设置FutureTask正常完成,实现和 setException类似,只是设置的状态不一样
protected void set(V v) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = v;
UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
finishCompletion();
}
}
cancel
//外部线程可以通过该方法的调用,取消任务的执行,mayInterruptIfRunning指明是否中断调用线程。
//此时,任务可能处于哪些状态:1、没有被执行 2、正在执行中 3、已经执行完成
public boolean cancel(boolean mayInterruptIfRunning) {
//如果当前线程已经完成(可能正在完成中,可能已经完成),返回false
if (!(state == NEW &&
UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
try { // 如果指定了中断线程,调用线程的interrupt()中断线程
if (mayInterruptIfRunning) {
try {
Thread t = runner;
if (t != null)
t.interrupt();
} finally { // final state
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
}
}
} finally {
//最终还是要调用完成任务的方法
finishCompletion();
}
return true;
}