线程可以通过实现Runnable接口,或者继承Thread实现,但是这两种方式在任务执行完成之后无法获取返回结果,于是就有了Callable接口,Future接口与FutureTask类配和来取得返回的结果。
Callable接口声明了一个方法call(),同时这个方法返回值为V,还可以跑出异常。
Future用来获取异步计算结果,提供以下方法声明
boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; 复制代码
public class FutureTask<V> implements RunnableFuture<V> public interface RunnableFuture<V> extends Runnable, Future<V> 复制代码
FutureTask类实现了RunnableFuture接口,FutureTask除了实现了Future接口外还实现了Runnable接口。FutureTask类是Future唯一实现类。
使用FutureTask时,根据FutureTask的构造函数可以看到FutureTask既可以接收Callable的实现类,也可以接收Runnable的实现类。当你传入的是Callable的实现类时,可以获取线程执行的结果;传入Runnable的实现类时,由于Runnable的实现没有返回值,需要传入一个你设置的线程完成标识,也就是result,然后当线程结束时会把你传入的result原值返回。
我们从ExecutorService接口中submit方法入手,看下AbstractExecutorService类对submit方法的具体实现。
使用submit方法提交任务时,都会通过newTaskFor方法转换成FutureTask对象。
所以ExecutorService接口中submit方法归根结底还是要把你传入的对象封装成FutureTask对象,并通过FutureTask类的内部实现来获取结果的,返回的Future接口对象也要依赖于FutureTask实例化的,所以无论是直接传入自己的Runnable、Callable实现类还是构建FutureTask传入,本质上都是通过FutureTask去实现,没有什么区别。