0

ExecutorService contains following methods:

  • invokeAll(Collection<? extends Callable<T>> tasks)
  • invokeAny(Collection<? extends Callable<T>> tasks)
  • submit(Callable<T> task)

I am confused about the use of terms submit vs invoke. Does it mean that invokeXyz() methods invoke those tasks immediately as soon as possible by underlying thread pool and submit() does some kind of scheduling of tasks submitted.

This answer says "if we want to wait for completion of all tasks, which have been submitted to ExecutorService". What does "wait for" here refers to?

MsA
  • 2,599
  • 3
  • 22
  • 47

1 Answers1

2

Both invoke..() and submit() will execute their tasks immediately (assuming threads are available to run the tasks). The difference is that invoke...() will wait for the tasks running in separate threads to finish before returning a result, whereas submit() will return immediately, meaning the task it executed is still running in another thread.

In other words, the Future objects returned from invokeAll() are guaranteed to be in a state where Future.isDone() == true. The Future object returned from submit() can be in a state where Future.isDone() == false.

We can easily demonstrate the timing difference.

public static void main(String... args) throws InterruptedException {
    Callable<String> c1 = () -> { System.out.println("Hello "); return "Hello "; };
    Callable<String> c2 = () -> { System.out.println("World!"); return "World!"; };
    List<Callable<String>> callables = List.of(c1, c2);
    ExecutorService executor = Executors.newSingleThreadExecutor();

    System.out.println("Begin invokeAll...");
    List<Future<String>> allFutures = executor.invokeAll(callables);
    System.out.println("End invokeAll.\n");

    System.out.println("Begin submit...");
    List<Future<String>> submittedFutures = callables.stream().map(executor::submit).collect(toList());
    System.out.println("End submit.");
}

And the result is that the callables print their Hello World message before the invokeAll() method completes; but the callables print Hello World after the submit() method completes.

/*
Begin invokeAll...
Hello
World!
End invokeAll.

Begin submit...
End submit.
Hello
World!
*/

You can play around with this code in an IDE by adding some sleep() time in c1 or c2 and watching as the terminal prints out. This should convince you that invoke...() does indeed wait for something to happen, but submit() does not.

jaco0646
  • 15,303
  • 7
  • 59
  • 83