Java中Future的初探

147 阅读2分钟

一个异步执行的任务的结果。我们可以通过Future来取消任务,查询任务是否完成,或者获取任务的返回值。 Future的优点是它可以让我们在主线程中不必等待任务的执行,而是可以继续做其他的事情,然后在合适的时候再来获取任务的结果。

Future

是Java 1.5引入的一个接口,它可以用来表示一个异步执行的任务的结果。我们可以通过Future来取消任务,查询任务是否完成,或者获取任务的返回值。Future的优点是它可以让我们在主线程中不必等待任务的执行,而是可以继续做其他的事情,然后在合适的时候再来获取任务的结果。

要使用Future,我们需要借助ExecutorService,它是一个线程池,可以用来执行Callable或Runnable类型的任务,并返回一个Future对象。Callable和Runnable的区别是,Callable可以有返回值,而Runnable没有。我们可以通过ExecutorService的submit方法来提交一个Callable任务,并得到一个Future对象。

例如,假设我们有一个计算平方数的任务:

public class SquareTask implements Callable<Integer> {
  private int input;

  public SquareTask(int input) {
    this.input = input;
  }

  @Override
  public Integer call() throws Exception {
    System.out.println("Calculating square of " + input);
    Thread.sleep(1000); // 模拟耗时操作
    return input * input;
  }
}

我们可以通过以下方式来执行这个任务,并获取Future对象:


ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(new SquareTask(10));

然后,我们可以通过Future对象来获取任务的结果:

try {
  // 如果任务还没有完成,get方法会阻塞等待
  Integer result = future.get();
  System.out.println("The square of 10 is " + result);
} catch (InterruptedException | ExecutionException e) {
  e.printStackTrace();
} finally {
  executor.shutdown(); // 关闭线程池
}

如果我们不想一直等待任务的结果,我们也可以给get方法传入一个超时时间:

try {
  // 如果在500毫秒内任务还没有完成,get方法会抛出TimeoutException
  Integer result = future.get(500, TimeUnit.MILLISECONDS);
  System.out.println("The square of 10 is " + result);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
  e.printStackTrace();
} finally {
  executor.shutdown(); // 关闭线程池
}

如果我们想取消一个正在执行或者还没有执行的任务,我们可以通过Future对象的cancel方法来实现:

boolean canceled = future.cancel(true); // 如果任务正在执行,传入true会中断它
if (canceled) {
  System.out.println("The task was canceled");
}

如果我们取消了一个任务,再调用get方法会抛出CancellationException。

以上就是我对Java中Future机制的简单介绍,希望对您有所帮助。如果您有任何疑问或建议,请随时回复我。