在上篇文章中我们分析线程池的实现过程中,如果是带返回值的callable 我们是直接封装成RunnableFuture,其实RunnableFuture的直接实现类是FutureTask。下面我们来看一下FutureTask的基本 实现。
FutureTask实际就是实现callable接口的线程,在线程过程中必须管理各种状态,如果线程执行完了,可以调用get方法取得的返回值;
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;
首先,我们先来看一下构造函数:
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
主要给本地变量callable赋值,同时设置当前状态是新建。
下面,我们再看一下run方法,因为FutureTask也是实现了Runable接口,
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 {
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;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
1,检测状态是否是NEW,如果不是直接返回,
2. 直接运行call方法获取返回,如果没有任何异常。 调用 set(result)方法给 返回值赋值,下面我们来看一下set方法:
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = v;
UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
finishCompletion();
}
set方法先设置状态为COMPLETING,如果设置成功,则给outcome赋值。再次更新状态为NORMAL.
我们再来看一下get方法:
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}
先判断是否已经完成,如果没有完成则进入等待awaitDone;否则返回值。
<span style="font-size:18px;">private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL) {
@SuppressWarnings("unchecked") V v = (V)x;
return v;
}
if (s >= CANCELLED)
throw new CancellationException();
throw new ExecutionException((Throwable)x);
}</span>
report方法只是简单的检测一下状态,如果是NORMAL则直接返回了。
重点我们来看一下 awaitDone方法:
private int awaitDone(boolean timed, long nanos)
throws InterruptedException {
long last = timed ? System.nanoTime() : 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 (q == null)
q = new WaitNode();
else if (!queued)
queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
q.next = waiters, q);
else if (timed) {
long now = System.nanoTime();
if ((nanos -= (now - last)) <= 0L) {
removeWaiter(q);
return state;
}
last = now;
LockSupport.parkNanos(this, nanos);
}
else
LockSupport.park(this);
}
}
主要是一下for里面调用LockSupport阻塞当前进程。