Future和Callable Future
是个接口:
1 2 3 4 5 6 7 8 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 ;}
可见它的功能主要包括:
下取消指令;
查询状态: 取消或者完成;
获取结果。// 这一点和callable一样。
回顾callable
的源码:
1 2 3 public interface Callable <V > { V call () throws Exception ; }
可见两者区别主要在于Future
并不定义任务详情,多了任务执行管理查询接口。 没有callable
的call函数。
实际使用的时候它们一般的分工如下:
1 Future<String> future = executorService.submit(new MyCallable());
FutureTask FutureTask是一个实际的类.
外部使用/接口: 1 2 3 4 5 6 7 Callable<Integer> callable = () -> new Random().nextInt(100 ); FutureTask<Integer> future = new FutureTask<>(callable); new Thread(future).start();System.out.println(future.get());
可以看出FutureTask
可以由Callable
构造,然后用于执行、异步获取结果。
内部组件: 源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class FutureTask <V > implements RunnableFuture <V > private volatile int state ; private static final int NEW = 0 ; private static final int COMPLETING = 1 ; private static final int NORMAL = 2 ; private static final int EXCEPTIONAL = 3 ; private static final int CANCELLED = 4 ; private static final int INTERRUPTING = 5 ; private static final int INTERRUPTED = 6 ; private Callable<V> callable; private Object outcome; private volatile Thread runner; private volatile WaitNode waiters;
其中状态可能的流转如下:(对应四个终结状态的生成)
1 2 3 4 NEW -> COMPLETING -> NORMAL NEW -> COMPLETING -> EXCEPTIONAL NEW -> CANCELLED NEW -> INTERRUPTING -> INTERRUPTED
// TODO 为啥异常状态不用负数标示呢?
其中RunnableFuture
接口是这样的:
1 2 3 public interface RunnableFuture <V > extends Runnable , Future <V > { void run () ; }
可见FutureTask
是Runnable
和Future
的结合, 拥有Future
的查询结果特性和Runnable
的定义计算任务的特性。
然而它的内部实现实际上是用了Callable
而不是Runnable
:
1 2 3 4 5 6 7 8 9 10 public FutureTask (Callable<V> callable) { if (callable == null ) throw new NullPointerException(); this .callable = callable; this .state = NEW; } public FutureTask (Runnable runnable, V result) { this .callable = Executors.callable(runnable, result); this .state = NEW; }
可以看到它只有两个构造函数,即使传入的Runnable
也会被装配成Callable
。
RunnableFuture/FutureTask与AbstractExecutorService 线程池的submit方法默认有如下3个实现: (来自AbstractExecutorService
类)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public Future<?> submit(Runnable task) { if (task == null ) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskFor(task, null ); execute(ftask); return ftask; } public <T> Future<T> submit (Runnable task, T result) { if (task == null ) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task, result); execute(ftask); return ftask; } public <T> Future<T> submit (Callable<T> task) { if (task == null ) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task); execute(ftask); return ftask; }
因此线程池中传入任务后,实际上会转化为RunnableFuture
.
其中构造RunnableFuture
的方法如下.
1 2 3 4 5 6 protected <T> RunnableFuture<T> newTaskFor (Runnable runnable, T value) { return new FutureTask<T>(runnable, value); } protected <T> RunnableFuture<T> newTaskFor (Callable<T> callable) { return new FutureTask<T>(callable); }
因此RunnableFuture
的实际实现,在线程池中默认是FutureTask
。
综上所述: 因此线程池中传入任务后,实际上会转化为FutureTask
.