持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
这篇文章我们来介绍一下Java 中的Future。
Future 是什么
Future 本身是一个接口,应用在多线程任务的场景中。在我们日常开发中,经常会遇到多线程开发的场景。一般实现就是实现Runnable接口或者继承Thread类来完成相应的业务逻辑。但是这两种实现方法都无法返回执行结果,也就是说无法拿到返回值。
但是我们肯定会遇到某种需要返回值的场景。使用以上两种方式来完成的多线程任务,我们课程通过共享对象或文件来实现目的,是无法直接拿到返回值的。但是如果这么做,又得考虑如何从共享对象或者文件中取值。另外我们需要考虑,如果业务执行过程中有报错,这个应该如何处理。对于Runnable 接口中的run 方法,是无法抛出异常的。
对于上述问题,java 中有Callable接口可以完成这两个任务,我们看一下接口定义:
public interface Callable<V> {
V call() throws Exception;
}
在Callable 接口中,有返回值,也可以抛出异常。但是我们转念再想,异常是可以抛出了,但是谁来接收呢?如果是要主线程来接收,那就肯定要等这个线程执行完成才可以结束,这样就变成了同步的过程了。于是,Java 中就引入了Future 的定义。
Future作为一个接口,就相当于一个容器的抽象,它可以保存Callable的返回结果。Future的逻辑就是在当我们将子任务放入线程池之后,处理完成相应的逻辑,然后再调用Future的get方法来获取结果返回的结果。另外,Future还可以控制子任务的执行过程。
Future 的方法
我们来看一下Future 接口中的各个方法:
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
对于这些方法,看方法名我们就可以大致了解对应的方法的作用了。我们这里着重介绍一些get方法。
- 调用
get方法的时候,如果执行的任务已经结束,那么就直接返回执行的结果。 - 如果任务没有完成完成,那么就会阻塞。
- 如果任务有异常抛出,那么在调用
get方法的时候会抛出ExecutionException异常。 - 如果任务被取消,那么调用
get方法的时候就抛出CancellationException异常。 - 在调用
get方法的时候,也可以带时间参数。如果在传入参数规定的时间内返回了结果,那么get方法正常;如果超过了参数中设定的时间,那么就会抛出TimeoutException异常。
总结
这篇文章主要说明了Future 接口的概念以及其出现原因。主要就是为了在多线程任务中可以获取结果,并可以捕获异常信息同时不会影响主线程的执行。Future接口在很多场景中都有实际应用,理解好Future很有实际意义。