官方解释:
一个可取消的异步计算。这个类提供了Future的基本实现,包括启动和取消计算、查询计算是否完成以及获取计算结果的方法。结果只能在计算完成后才能获取;如果计算尚未完成,get方法会阻塞。一旦计算完成,就无法重新启动或取消(除非使用runAndReset)。
一个FutureTask可以包装一个Callable或Runnable对象。因为FutureTask实现了Runnable,所以一个FutureTask可以被提交给一个Executor进行执行。
除了作为独立类之外,这个类还提供了protected功能,这在创建自定义任务类时可能会很有用。
一、源码解析
FutureTask字面上意思是“未来任务”,我觉得大概率就是刚提交的task,直接get并不能获取到结果,得等待任务执行完成返回才行,所以说是未来的任务。
我们先来看看它的继承类图:
- 实现了Runnable,不必多说能够作为线程体启动
- 主要实现Future的功能
Future接口规范
// 取消任务,并不是中断当前任务执行。
// 参数为true的话,只是线程被设置为中断,具体是否会停止不一定,得看当前线程是否满足线程停止条件
// 其次如果线程被取消同时线程仍然正常执行结束了,在get的时候会进行控制,并不会得到值
boolean cancel(boolean mayInterruptIfRunning);
/**
* Returns {@code true} if this task was cancelled before it completed
* normally.
*
* @return {@code true} if this task was cancelled before it completed
*/
boolean isCancelled();
/**
* Returns {@code true} if this task completed.
*
* Completion may be due to normal termination, an exception, or
* cancellation -- in all of these cases, this method will return
* {@code true}.
*
* @return {@code true} if this task completed
*/
boolean isDone();
取执行结果,会阻塞
V get() throws InterruptedException, ExecutionException;
// 获取执行结果,并且设计超时时间,如果超时抛出异常
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
成员变量
/**
* The run state of this task, initially NEW. The run state
* transitions to a terminal state only in methods set,
* setException, and cancel. During completion, state may take on
* transient values of COMPLETING (while outcome is being set) or
* INTERRUPTING (only while interrupting the runner to satisfy a
* cancel(true)). Transitions from these intermediate to final
* states use cheaper ordered/lazy writes because values are unique
* and cannot be further modified.
*
* Possible state transitions:
* NEW -> COMPLETING -> NORMAL
* NEW -> COMPLETING -> EXCEPTIONAL
* NEW -> CANCELLED
* NEW -> INTERRUPTING -> INTERRUPTED
*/
// 注意上面的状态转换,虽然我们平时敲代码并不会太关注它内部的细节。
// 维护线程当前的状态,比较重要,因为执行线程是不受外界影响的(并不是说你让他中断就能中断的),所以需要状态来标记它
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 */
// 当前的callable
private Callable<V> callable;
/** The result to return or exception to throw from get() */
// 返回值 注意是object类型,所以说什么都能放
private Object outcome; // non-volatile, protected by state reads/writes
/** The thread running the callable; CASed during run() */
// 用于记录目标线程,也就是运行这个FutureTask的线程
private volatile Thread runner;
/** Treiber stack of waiting threads */
// get阻塞排队的线程
private volatile WaitNode waiters
我们可以看到主要的几个参数:
- callable:有返回值的线程任务
- outcome:存放get的返回值
- runner:执行当前task的线程,线程的状态依托于FutureTask来表现
- waiters:正在get的等待线程
构造函数
/**
* Creates a {@code FutureTask} that will, upon running, execute the
* given {@code Callable}.
*
* @param callable the callable task
* @throws NullPointerException if the callable is null
*/
// 接收有返回值的callable
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
/**
* Creates a {@code FutureTask} that will, upon running, execute the
* given {@code Runnable}, and arrange that {@code get} will return the
* given result on successful completion.
*
* @param runnable the runnable task
* @param result the result to return on successful completion. If
* you don't need a particular result, consider using
* constructions of the form:
* {@code Future<?> f = new FutureTask<Void>(runnable, null)}
* @throws NullPointerException if the runnable is null
*/
// 接收无返回值的runnable,第二个参数为预置返回值(可以传null)
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
这里我们可以看一下,无返回值runnable如何被包装为有返回值callable的。
/**
* Returns a {@link Callable} object that, when
* called, runs the given task and returns the given result. This
* can be useful when applying methods requiring a
* {@code Callable} to an otherwise resultless action.
* @param task the task to run
* @param result the result to return
* @param <T> the type of the result
* @return a callable object
* @throws NullPointerException if task null
*/
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
/**
* A callable that runs given task and returns given result
*/
// 使用了适配器模式,值得学习,提高我们流水线式的代码水平,一个适配器继承了callable
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
// 返回构造器指定的result
return result;
}
}
cancel方法
public boolean cancel(boolean mayInterruptIfRunning) {
// 如果状态为NEW,那么mayInterruptIfRunning=true状态变为中断否则为取消
if (!(state == NEW &&
UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
try { // in case call to interrupt throws exception
// mayInterruptIfRunning=true,设置线程状态为中断,同时设置futureTask为状态为中断
if (mayInterruptIfRunning) {
try {
Thread t = runner;
if (t != null)
t.interrupt();
} finally { // final state
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
}
}
} finally {
// 这一步比较重要回来看,主要是唤醒其他调用get的阻塞线程
finishCompletion();
}
return true;
}
get方法
/**
* @throws CancellationException {@inheritDoc}
*/
public V get() throws InterruptedException, ExecutionException {
int s = state;
// 判断状态,符合的状态才能够获取返回值
if (s <= COMPLETING)
// 获取返回值
s = awaitDone(false, 0L);
// 返回 这里面比较重要!
return report(s);
}
/**
* Returns result or throws exception for completed task.
*
* @param s completed state value
*/
// 先看report
@SuppressWarnings("unchecked")
private V report(int s) throws ExecutionException {
Object x = outcome;
// 只有NORMAL状态才会返回值,其他状态都会抛出异常
// 也就是说即使目标线程正常执行完了,funtureTask获取到了正常返回值,因为取消执行并不能让线程终止,这里可以自行查阅线程终止条件。
// 但是由于对futureTask的取消操作,还是会抛出异常的
if (s == NORMAL)
return (V)x;
if (s >= CANCELLED)
throw new CancellationException();
// 如果目标线程执行出现异常,那么返回值是异常
throw new ExecutionException((Throwable)x);
}
/**
* Awaits completion or aborts on interrupt or timeout.
*
* @param timed true if use timed waits
* @param nanos time to wait, if timed
* @return state upon completion
*/
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
final long deadline = timed ? System.nanoTime() + nanos : 0L;
WaitNode q = null;
boolean queued = false;
for (;;) {
// 判断当前调用get的线程是否被中断过,如果中断出队,并且抛出异常
if (Thread.interrupted()) {
removeWaiter(q);
throw new InterruptedException();
}
int s = state;
// 如果目标线程状态不为NEW、COMPLETING,返回状态
if (s > COMPLETING) {
if (q != null)
q.thread = null;
return s;
}
// 目标线程正在执行
else if (s == COMPLETING) // cannot time out yet
Thread.yield();
// 两个if还没获取到数据,当前线程进入等待队列
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
// park(this)源码获取了当前线程哦,让当前线程sleep,详细内容学习LockSupport
LockSupport.park(this);
}
}
/**
* Tries to unlink a timed-out or interrupted wait node to avoid
* accumulating garbage. Internal nodes are simply unspliced
* without CAS since it is harmless if they are traversed anyway
* by releasers. To avoid effects of unsplicing from already
* removed nodes, the list is retraversed in case of an apparent
* race. This is slow when there are a lot of nodes, but we don't
* expect lists to be long enough to outweigh higher-overhead
* schemes.
*/
// 去除node中thread为null的节点
private void removeWaiter(WaitNode node) {
if (node != null) {
node.thread = null;
retry:
for (;;) { // restart on removeWaiter race
for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
s = q.next;
if (q.thread != null)
pred = q;
else if (pred != null) {
pred.next = s;
if (pred.thread == null) // check for race
continue retry;
}
else if (!UNSAFE.compareAndSwapObject(this, waitersOffset,
q, s))
continue retry;
}
break;
}
}
}
/**
* @throws CancellationException {@inheritDoc}
*/
// 带有超时时间的get
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);
}
线程运行实体Run方法
这个方法是运行的核心。
public void run() {
// 状态校验
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
// 获取callable
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
// 执行call
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
// 将返回值放入到outcome中!!!!!!!
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;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
/**
* Sets the result of this future to the given value unless
* this future has already been set or has been cancelled.
*
* <p>This method is invoked internally by the {@link #run} method
* upon successful completion of the computation.
*
* @param v the value
*/
protected void set(V v) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
// 放入值
outcome = v;
// 变更状态,NORMAL
UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
finishCompletion();
}
}
/**
* Causes this future to report an {@link ExecutionException}
* with the given throwable as its cause, unless this future has
* already been set or has been cancelled.
*
* <p>This method is invoked internally by the {@link #run} method
* upon failure of the computation.
*
* @param t the cause of failure
*/
// 放入异常
protected void setException(Throwable t) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = t;
UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
finishCompletion();
}
}
/**
* Removes and signals all waiting threads, invokes done(), and
* nulls out callable.
*/
// 将等待队列中所有线程唤醒以及出队,他们会继续执行get方法
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;
}
}
}
这里了也要着重看一下finishCompletion方法,它唤醒了所有对该FutureTask执行get阻塞的线程。
runAndReset
在不设置结果的情况下执行计算,然后将此未来重置为初始状态,如果计算遇到异常或被取消,则无法执行此操作。这是为与本质上执行多次的任务一起使用而设计的。
/**
* Executes the computation without setting its result, and then
* resets this future to initial state, failing to do so if the
* computation encounters an exception or is cancelled. This is
* designed for use with tasks that intrinsically execute more
* than once.
*
* @return {@code true} if successfully run and reset
*/
protected boolean runAndReset() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return false;
boolean ran = false;
int s = state;
try {
Callable<V> c = callable;
if (c != null && s == NEW) {
try {
// 没有result
c.call(); // don't set result
ran = true;
} catch (Throwable ex) {
setException(ex);
}
}
} 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
s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
return ran && s == NEW;
}
二、总结
泳道图:(粗略)
个人理解图:
记住在Java中,所有的对象都在堆中,线程只有各自的栈内存,对象不属于任何一个线程。线程是运行的实体,每一个线程都有一个Thread对象去持有操作(这里底层都是C++操作的)。