任务提交有两种方式:
- submit 提交Runable任务
- execute 提交Callable任务
submit 提交Runable
- 方式1 future返回null
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
- 方式2 future返回指定结果
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;
}
- 方式3 future返回Callable的结果T
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
跟入newTaskFor代码,再看 FutureTask的构造可知,以上三种方式都是将提交的任务转换为一个callable对象,包装到FutureTask实例中进行处理,感兴趣的runnable的返回结果处理是这样的:
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
callable 在创建RunnableAdapter
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
RunnableAdapter 里能看到call的执行逻辑,执行完run,返回result;
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
execute 提交Callable任务
当Callable对象构造完毕后,放入RunnableFuture实例中;FutureTask本身是Runnable接口,作为Executor接口中声明的execute方法的参数进行处理,必定会调用其run方法,看其实现:
- FutureTask#run()
简化以下其run方法的代码,可以看出会执行callable#call方法,并保存结果。
public void run() {
Callable<V> c = callable;
result = c.call();
set(result);
}
网友评论