在使用多线程的场景中,线程A如何想要获取线程B的执行结果,则需要一直等待线程B执行完毕后才能取到结果,而Future则是线程A在提交线程B时,返回一个Future,线程A通过调用Future.get获取线程B的结果,如果此时线程B还未执行完毕,则线程A调用Future.get会阻塞;
1. Future接口
Future是一个接口,其中FutureTask是Future的一种实现;
public interface Future<V> {
// 取消一个任务,并返回取消结果。参数表示是否中断线程
boolean cancel(boolean mayInterruptIfRunning);
// 判断任务是否被取消
boolean isCancelled();
// 判断当前任务是否执行完毕,包括正常执行完毕、执行异常或者任务取消。
boolean isDone();
// 获取任务执行结果,任务结束之前会阻塞。
V get() throws InterruptedException, ExecutionException;
// 在指定时间内尝试获取执行结果。若超时则抛出超时异常
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
2. 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;
// 需要执行的任务
private Callable<V> callable;
// 结果值,或异常信息
private Object outcome; // non-volatile, protected by state reads/writes
// 正在执行的线程
private volatile Thread runner;
// 等待者链表
private volatile WaitNode waiters;
FutureTask状态流转
3. FutureTask构造器
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
public FutureTask(Runnable runnable, V result) {
// 将runnable转换成Callable,并且传进来的result是啥get的时候结果就是啥
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
4. run方法
FutureTask实现自RunnableFuture,而RunnableFuture 继自 Runnable, Future,所以FutureTask一定有一个run方法:
public void run() {
// 状态必须是新建,将runner设置为当前线程
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
// 执行callable方法
result = c.call();
// 成功标识
ran = true;
} catch (Throwable ex) {
// 出现异常设置状态和响应值
result = null;
ran = false;
setException(ex);
}
// 成功
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
// 如果状态为 INTERRUPTING 或者 INTERRUPTED 时,表示线程被中断
if (s >= INTERRUPTING)
// 如果正在被中断,则当前线程也不要执行了,一直让出资源就可以了
handlePossibleCancellationInterrupt(s);
}
}
protected void setException(Throwable t) {
// 将状态改为COMPLETING
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
// 设置返回值为异常信息
outcome = t;
// 设置状态为 EXCEPTIONAL
UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
finishCompletion();
}
}
// 唤醒park线程
// 当线程调用future.get时,如果此时还没有计算结束,会进行park操作;
private void finishCompletion() {
// assert state > COMPLETING;
for (WaitNode q; (q = waiters) != null;) {
if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {
for (;;) {
Thread t = q.thread;
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
}
// 成功时,设置状态和响应值,并唤醒等待线程
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = v;
UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
finishCompletion();
}
5. cancel方法
// mayInterruptIfRunning true 表示中断
public boolean cancel(boolean mayInterruptIfRunning) {
// 如果状态!=null 并且将状态改为INTERRUPTING或CANCELLED
if (!(state == NEW &&
UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
try { // in case call to interrupt throws exception
if (mayInterruptIfRunning) {
try {
// 将执行callable的线程进行中断;
Thread t = runner;
if (t != null)
t.interrupt();
} finally { // final state
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
}
}
} finally {
finishCompletion();
}
return true;
}
6. cancel方法
public V get() throws InterruptedException, ExecutionException {
int s = state;
// 如果还到达终态,则等待
if (s <= COMPLETING)
s = awaitDone(false, 0L);
// 否则获取响应值;
return report(s);
}
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
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;
}
else if (s == COMPLETING) // cannot time out yet
Thread.yield();
else if (q == null)
q = new WaitNode();
else if (!queued)
queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
q.next = waiters, q);
else if (timed) {
nanos = deadline - System.nanoTime();
if (nanos <= 0L) {
removeWaiter(q);
return state;
}
LockSupport.parkNanos(this, nanos);
}
else
LockSupport.park(this);
}
}
// 这里有可能是因为callable被执行完唤醒,也可能是因为异常原因被唤醒;
private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL)
// 如果正常,则响应返回值
return (V)x;
if (s >= CANCELLED)
// 执行过程中出现了异常,抛出异常;
throw new CancellationException();、
// 否则,就是EXCEPTIONAL状态了
throw new ExecutionException((Throwable)x);
}