ExecutorService.submit(Runnable task,T result)中的'result'是什么做的?

Dog*_*xed 20 java synchronization

看看javadocs,它只是说

<T> Future<T> submit(Runnable task, T result)

提交Runnable任务以执行并返回表示该任务的Future.Future的get方法将在成功完成后返回给定的结果.

参数:

任务 - 要提交的任务

结果 - 返回的结果

但它对结果有什么影响?它存储了什么吗?它只是使用结果类型来指定类型Future<T>

dog*_*ane 14

它对结果没有任何作用 - 只是持有它.任务成功完成后,调用future.get()将返回您传入的结果.

以下是Executors $ RunnableAdapter的源代码,它显示在任务运行后,返回原始结果:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

是的,结果的泛型类型应该与返回的Future的类型相匹配.

  • 我很好奇这可能有用 (3认同)

aal*_*lku 8

Runnable不返回任何内容,Future必须返回一些内容,因此此方法允许您预定义返回的未来的结果.

如果你不想返回一个东西,你可以返回null,而我Void认为这种类型的东西是存在的.

Future<Void> myFuture = executor.submit(myTask, null);
Run Code Online (Sandbox Code Playgroud)

您知道在这种情况下myFuture.get()会返回null,但只有在任务运行之后才会返回,因此您将使用它来等待并抛出任务中抛出的任何异常.

try {
  myFuture.get();
  // After task is executed successfully
  ...
} catch (ExecutionException e) {
  Throwable c = e.getCause();
  log.error("Something happened running task", c);
  // After task is aborted by exception
  ...
}
Run Code Online (Sandbox Code Playgroud)


G. *_*ies 5

您可以改变在任务期间传入的对象。例如:

final String[] mutable = new String[1];
Runnable r = new Runnable() {
    public void run() {
        mutable[0] = "howdy";
    }
};
Future<String[]> f = executorService.submit(r, mutable);
String[] result = f.get();
System.out.println("result[0]: " + result[0]);
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,它输出:

result[0]: howdy
Run Code Online (Sandbox Code Playgroud)

  • 这个答案显示了一些有趣的东西,但显示它的代码不正确。根据使用的 executorService 类,任务可能会在不同的线程中运行(可能会),并且可变数组可能会被缓存并显示线程之间的内存一致性错误。您应该同步或使用“AtomicReference&lt;String&gt;”。如果您想获得结果,您也可以提交 Callable&lt;String&gt;` 而不是 Runnable。 (2认同)