ffset, NEW,
mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
// 如果状态修改成功后,判断是否允许中断线程,如果允许,则调用Thread的interrupt方法中断
try { // in case call to interrupt throws exception
if (mayInterruptIfRunning) {
try {
Thread t = runner;
if (t != null)
t.interrupt();
} finally { // final state
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
}
}
} finally {
// 取消后的收尾工作
finishCompletion();
}
return true;
}
2.6 isDone/isCancelled方法介绍
isDone方法用于判断FutureTask是否已经完成;isCancelled方法用来判断FutureTask是否已经取消,这两个方法都是通过状态位来判断的。
public boolean isCancelled() {
return state >= CANCELLED;
}
public boolean isDone() {
return state != NEW;
}
2.7 finishCompletion方法介绍
我们看下finishCompletion方法都做了哪些工作。
// 删除所有等待线程并发出信号,最后执行done方法
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
}
我们看到done方法是一个受保护的空方法,此处没有任何逻辑,由其子类去根据自己的业务去实现相应的逻辑。例如:java.util.concurrent.ExecutorCompletionService.QueueingFuture。
protected void done() { }
3、总结
通过源码解读可以了解到Future的原理:
第一步:主线程将任务封装成一个Callable对象,通过submit方法提交到线程池去执行。
第二步:线程池执行任务的run方法,主线程则可以继续执行其他逻辑。
第三步:线程池中方法执行完成后将结果赋值到outcome属性上,并修改任务状态。
第四步:主线程在需要拿到异步任务结果的时候,主动调用fugure.get()方法来获取结果。
第五步:如果异步线程在执行过程中发生异常,则会在调用future.get()方法的时候抛出来。
以上就是对于FutureTask的分析,我们可以了解FutureTask任务执行的方式以及Future.get已阻塞的方式获取线程执行的结果原理,并且从代码中可以了解FutureTask的任务执行状态以及状态的变化过程。
作者:京东物流 丁冬
来源:京东云开发者社区 自猿其说Tech