ExecutorService总共有三个submit方法:

Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);
<T> Future<T> submit(Callable<T> task);

在AbstractExecutorService中的实现如下:

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;
}

实际返回的是FutureTask对象:

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);
}

FutureTask的继承关系如下:

public class FutureTask<V> implements RunnableFuture<V> {
    ......
}

public interface RunnableFuture<V> extends Runnable, Future<V> {
    ......
}

execute执行FutureTask的run方法时,实际执行的是Callable的call方法,并set call()方法的返回值

public void run() {
    ......
    Callable<V> c = callable;
    ......
    result = c.call();
    ......
    set(result);
    ......
}

protected void set(V v) {
    ......
    outcome = v;
    ......
}

最终调用submit()返回的、Future的、get()方法时,实际返回的是call()方法的返回值

public V get() throws InterruptedException, ExecutionException {
    ......
    return report(s);
}

private V report(int s) throws ExecutionException {
    Object x = outcome;
    if (s == NORMAL)
        return (V)x;
    ......
}

再回到FutureTask构造方法

  • 入参为Runnable时,执行Executors.callable()包装后返回的Callable类,返回值Future.get()的结果为null
  • 入参为Runnable和result时,执行Executors.callable()包装后返回的Callable类,返回值Future.get()的结果为传入的result
  • 入参为Callable时,则直接执行的传入的Callable对象的call()方法,返回值Future.get()的结果为call()的返回值
public FutureTask(Runnable runnable, V result) {
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;       // ensure visibility of callable
}

public FutureTask(Callable<V> callable) {
    if (callable == null)
        throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;       // ensure visibility of callable
}

查看Executors.callable()方法,新建内部类RunnableAdapter,call()方法在执行Runnable的run()方法之后返回传入的result

public static <T> Callable<T> callable(Runnable task, T result) {
    ......
    return new RunnableAdapter<T>(task, 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;
    }
}

综上所述:

  • Future<?> submit(Runnable task);
    • 执行Runnable的run()方法之后,Future.get()返回null
  • <T> Future<T> submit(Runnable task, T result);
    • 执行Runnable的run()方法之后,Future.get()返回传入的result
  • <T> Future<T> submit(Callable<T> task);
    • 执行Callable的call()方法之后,Future.get()返回call()方法返回值

 

补充:

调用submit(Runnable task)时,如果入参本身为FutureTask,submit()返回的Futrue.get()仍然为null,将与预期不符。

解决办法:调用线程池的execute()方法

ExecutorService pool = Executors.newCachedThreadPool();
FutureTask<Boolean> futureTask = new FutureTask<>(new Callable<Boolean>() {
    @Override
    public Boolean call() throws Exception {
        return Boolean.FALSE;
    }
});
pool.execute(futureTask);
Boolean result = futureTask.get();

 

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐