FutureTask在JDK1.5引入,在IDEA中查看继承关系图:
A FutureTask can be used to wrap a Callable or Runnable object. Because FutureTask implements Runnable, a FutureTask can be submitted to an Executor for execution.
源码中的一段话介绍,FutureTask作为Runnable、Callable的包装类对象,可以被线程池执行或者提交,一般用于线程池获取异步计算结果。
FutureTask也提供了get方法来获得任务执行返回结果。
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}
get方法是阻塞的,如果当前状态值state<=COMPLETETING就会调用awaitDone方法直到返回结果。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;
其循环过程为:NEW -> COMPLETING -> NORMAL NEW -> COMPLETING -> EXCEPTIONAL NEW -> CANCELED NEW -> INTERRUPTING -> INTERRUPTED。state的默认值为0也就是处于NEW状态。
通过一段代码简单演示FutureTask的使用。
package futuretask;
import java.util.concurrent.*;
public class FutureTaskTest {
private final static ConcurrentMap<Object, Future<String>> taskCache = new ConcurrentHashMap<>();
private static String executionTask(String taskName) throws ExecutionException, InterruptedException {
while (true) {
Future<String> future = taskCache.get(taskName);
if (future == null) {
Callable<String> task = () -> {
TimeUnit.SECONDS.sleep(5);
return taskName;
};
FutureTask<String> futureTask = new FutureTask<>(task);
future = taskCache.putIfAbsent(taskName, futureTask);
if (future == null) {
future = futureTask;
futureTask.run();
}
}
try {
return future.get();
} catch (CancellationException e) {
taskCache.remove(taskName, future);
}
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
String testTask = executionTask("task");
System.out.println(testTask);
}
}