What does 'result' in ExecutorService.submit(Runnable task, T result) do?
Asked Answered
W

3

21

Looking at the javadocs it just says

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

Submits a Runnable task for execution and returns a Future representing that task. The Future's get method will return the given result upon successful completion.

Parameters:

task - the task to submit

result - the result to return

but what does it do with result? does it store anything there? does it just use the type of result to specify the type of Future<T>?

Wandawander answered 23/6, 2011 at 15:20 Comment(0)
S
16

It doesn't do anything with the result - just holds it. When the task successfully completes, calling future.get() will return the result you passed in.

Here is the source code of Executors$RunnableAdapter, which shows that after the task has run, the original result is returned:

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

And yes, the generic type of the result should match that of the returned Future.

Southwick answered 23/6, 2011 at 15:26 Comment(2)
Furthermore, from the FutureTask constructor api: "result - the result to return on successful completion. If you don't need a particular result, consider using constructions of the form: Future<?> f = new FutureTask<Object>(runnable, null)"Csc
i am curious where this might be usefulDestructive
A
11

Runnable does not return anything and Future must return something so this method allows you to predefine the result of the returned future.

If you don't want to return a thing you can return null and I think the Void type exists to express that kind of things.

Future<Void> myFuture = executor.submit(myTask, null);

You know myFuture.get() will return null in this case but only after the task has been run, so you would use it to wait and throw any exception that were thrown in the task.

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
  ...
}
Adoree answered 23/6, 2011 at 15:37 Comment(0)
J
6

You can mutate the object that was passed-in during the task. For example:

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

When I run this code it outputs:

result[0]: howdy
Jonme answered 19/4, 2017 at 0:59 Comment(1)
This answer shows something interesting but the code to show it is not correct. depending on the executorService class used the task may run in a different thread (probably will) and the mutable array might be cached and show memory consistency error between threads. You should synchronize or use an AtomicReference<String> instead. Also you can submit a Callable<String> instead of a Runnable if you want to get a result.Adoree

© 2022 - 2024 — McMap. All rights reserved.