What is the difference between ExecutorService.submit and ExecutorService.execute in this code in Java?
As you see from the JavaDoc execute(Runnable)
does not return anything.
However, submit(Callable<T>)
returns a Future
object which allows a way for you to programatically cancel the running thread later as well as get the T
that is returned when the Callable
completes. See JavaDoc of Future for more details
Future<?> future = executor.submit(longRunningJob);
...
//long running job is taking too long
future.cancel(true);
Moreover,
if future.get() == null
and doesn't throw any exception then Runnable executed successfully
The difference is that execute
simply starts the task without any further ado, whereas submit
returns a Future
object to manage the task. You can do the following things with the Future
object:
- Cancel the task prematurely, with the
cancel
method. - Wait for the task to finish executing, with
get
.
The Future
interface is more useful if you submit a Callable
to the pool. The return value of the call
method will be returned when you call Future.get
. If you don't maintain a reference to the Future
, there is no difference.
execute:
Use it for fire and forget calls
submit:
Use it to inspect the result of method call and take appropriate action on Future
objected returned by the call
Major difference: Exception
handling
submit()
hides un-handled Exception
in framework itself.
execute()
throws un-handled Exception
.
Solution for handling Exceptions with submit()
-
Wrap your
Callable or Runnable code in try{} catch{} block
OR
-
Keep
future.get() call in try{} catch{} block
OR
-
implement your own
ThreadPoolExecutor
and overrideafterExecute
method
Regarding tour other queries on
invokeAll:
Executes the given tasks, returning a list of Futures holding their status and results when all complete or the timeout expires, whichever happens first.
invokeAny:
Executes the given tasks, returning the result of one that has completed successfully (i.e., without throwing an exception), if any do before the given timeout elapses.
Use invokeAll
if you want to wait for all submitted tasks to complete.
Use invokeAny
if you are looking for successful completion of one task out of N submitted tasks. In this case, tasks in progress will be cancelled if one of the tasks completes successfully.
Related post with code example:
Choose between ExecutorService's submit and ExecutorService's execute