线程能够经过实现Runnable接口,或者继承Thread实现,可是这两种方式在任务执行完成以后没法获取返回结果,因而就有了Callable接口,Future接口与FutureTask类配和来取得返回的结果。bash
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惟一实现类。spa
使用FutureTask时,根据FutureTask的构造函数能够看到FutureTask既能够接收Callable的实现类,也能够接收Runnable的实现类。当你传入的是Callable的实现类时,能够获取线程执行的结果;传入Runnable的实现类时,因为Runnable的实现没有返回值,须要传入一个你设置的线程完成标识,也就是result,而后当线程结束时会把你传入的result原值返回。线程
咱们从ExecutorService接口中submit方法入手,看下AbstractExecutorService类对submit方法的具体实现。3d
使用submit方法提交任务时,都会经过newTaskFor方法转换成FutureTask对象。code
因此ExecutorService接口中submit方法归根结底仍是要把你传入的对象封装成FutureTask对象,并经过FutureTask类的内部实现来获取结果的,返回的Future接口对象也要依赖于FutureTask实例化的,因此不管是直接传入本身的Runnable、Callable实现类仍是构建FutureTask传入,本质上都是经过FutureTask去实现,没有什么区别。cdn