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);}}
