FutureTask在JDK1.5引入,在IDEA中查看继承关系图:
    FutureTask.png

    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方法来获得任务执行返回结果。

    1. public V get() throws InterruptedException, ExecutionException {
    2. int s = state;
    3. if (s <= COMPLETING)
    4. s = awaitDone(false, 0L);
    5. return report(s);
    6. }

    get方法是阻塞的,如果当前状态值state<=COMPLETETING就会调用awaitDone方法直到返回结果。FutureTask内部定义了一组任务执行状态

    1. private volatile int state;
    2. private static final int NEW = 0;
    3. private static final int COMPLETING = 1;
    4. private static final int NORMAL = 2;
    5. private static final int EXCEPTIONAL = 3;
    6. private static final int CANCELLED = 4;
    7. private static final int INTERRUPTING = 5;
    8. private static final int INTERRUPTED = 6;

    其循环过程为:NEW -> COMPLETING -> NORMAL NEW -> COMPLETING -> EXCEPTIONAL NEW -> CANCELED NEW -> INTERRUPTING -> INTERRUPTED。state的默认值为0也就是处于NEW状态。
    通过一段代码简单演示FutureTask的使用。

    1. package futuretask;
    2. import java.util.concurrent.*;
    3. public class FutureTaskTest {
    4. private final static ConcurrentMap<Object, Future<String>> taskCache = new ConcurrentHashMap<>();
    5. private static String executionTask(String taskName) throws ExecutionException, InterruptedException {
    6. while (true) {
    7. Future<String> future = taskCache.get(taskName);
    8. if (future == null) {
    9. Callable<String> task = () -> {
    10. TimeUnit.SECONDS.sleep(5);
    11. return taskName;
    12. };
    13. FutureTask<String> futureTask = new FutureTask<>(task);
    14. future = taskCache.putIfAbsent(taskName, futureTask);
    15. if (future == null) {
    16. future = futureTask;
    17. futureTask.run();
    18. }
    19. }
    20. try {
    21. return future.get();
    22. } catch (CancellationException e) {
    23. taskCache.remove(taskName, future);
    24. }
    25. }
    26. }
    27. public static void main(String[] args) throws ExecutionException, InterruptedException {
    28. String testTask = executionTask("task");
    29. System.out.println(testTask);
    30. }
    31. }