Java 中Future 接口的使用

427 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

Future 使用示例

对于Future 的使用方法以及使用场景,我们来举例介绍一下。

public class Test {
  static class CallableAssignment implements Callable<Integer> {
    @Override
    public Integer call() throws  Exception {
      throw new IllegalArgumentException("抛出异常");
    }
  }
  public static void main(String [] args) {
    ExecutorService executorService = Executors.newFixedThreadPool(1);
    Future<Integer> future = executorService.submit(new CallableAssignment());
    try {
      System.out.println("执行其他任务");
      Thread.sleep(3000);
      System.out.println("其他任务执行完成");
      System.out.println(future.isDone());
      System.out.println("over");
      future.get();
    }catch(InterruptedException e) {
      System.out.println("InterruptedException");
      e.printStackTrace();
    }catch(ExecutionException e) {
      System.out.println("ExecutionException");
      e.printStackTrace();
    }
    executorService.shutdown();
  }
}

触发执行上面的main 方法,我们会得到以下结果:

执行其他任务
其他任务执行完成
true
over
ExecutionException
java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: 抛出异常
	at java.util.concurrent.FutureTask.report(FutureTask.java:122)
	at java.util.concurrent.FutureTask.get(FutureTask.java:192)
	at Test.main(Test.java:19)
Caused by: java.lang.IllegalArgumentException: 抛出异常
	at Test$CallableAssignment.call(Test.java:7)
	at Test$CallableAssignment.call(Test.java:4)

我们可以发现,在上述代码逻辑中,在将子线程任务置入线程池之后,主线程可以执行其他任务。当子线程执行完成之后,课程通过get 方法获取其执行结果。同时,在任务执行过程中,子线程抛出的异常会以ExecutionException 类型进行捕获。

FutureTask 类的使用

我们首先来看FutureTask 的Diagram:

image.png

通过这张图,我们可以看到,FutureTask 的实现关系,它不仅实现了Runnable 接口,同时也实现了Future 接口。所以它既可以执行,也可以保存结果。

我们举例来看一下FutureTask 的使用方法:

class CallableAssignment implements Callable<Integer> {
  @Override
  public Integer call() throws Exception {
    System.out.println("开始");
    int result = 0;
    for (int i = 0; i <250; i++) {
      result += i;
    }
    return result;
  }
}

public class Test {
  public  static void main(String [] args) throws InterruptedException, ExecutionException {
    CallableAssignment callableAssignment = new CallableAssignment();
    FutureTask<Integer> futureTask = new FutureTask<>(callableAssignment);
    ExecutorService executorService = Executors.newFixedThreadPool(1);
    // 由于FutureTask 实现了Runnable 接口,所以我们也可以这样执行:new Thread(futureTask).start();
    executorService.submit(futureTask);
    System.out.println("等待执行");
    Thread.sleep(10000);
    System.out.println(futureTask.get());
    executorService.shutdown();
  }
}

执行结果为:

等待执行
开始
31125

在上述逻辑中,我们可以发现,FutureTask 的实例,不仅可以按照Future 的使用方法进行编写,同时也可以按照Runnable 的方法进行编写。所以它的灵活性还是很强的。

总结

这篇文章介绍了Future 的使用方法以及具体的使用示例,可以给到读者很好的参考。