What is the difference between ExecutorService.submit and ExecutorService.execute in this code in Java?
Solution 1
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
Solution 2
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.
Solution 3
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
Executes the given tasks, returning a list of Futures holding their status and results when all complete or the timeout expires, whichever happens first.
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
Solution 4
A main difference between the submit() and execute() method is that ExecuterService.submit()can return result of computation because it has a return type of Future, but execute() method cannot return anything because it's return type is void. The core interface in Java 1.5's Executor framework is the Executor interface which defines the execute(Runnable task) method, whose primary purpose is to separate the task from its execution.
Any task submitted to Executor can be executed by the same thread, a worker thread from a thread pool or any other thread.
On the other hand, submit() method is defined in the ExecutorService interface which is a sub-interface of Executor and adds the functionality of terminating the thread pool, along with adding submit() method which can accept a Callable task and return a result of computation.
Similarities between the execute() and submit() as well:
- Both submit() and execute() methods are used to submit a task to Executor framework for asynchronous execution.
- Both submit() and execute() can accept a Runnable task.
- You can access submit() and execute() from the ExecutorService interface because it also extends the Executor interface which declares the execute() method.
Apart from the fact that submit() method can return output and execute() cannot, following are other notable differences between these two key methods of Executor framework of Java 5.
- The submit() can accept both Runnable and Callable task but execute() can only accept the Runnable task.
- The submit() method is declared in ExecutorService interface while execute() method is declared in the Executor interface.
- The return type of submit() method is a Future object but return type of execute() method is void.
Solution 5
Submit - Returns Future object, which can be used to check result of submitted task. Can be used to cancel or to check isDone etc.
Execute - doesn't return anything.
brain storm
Updated on July 08, 2022Comments
-
brain storm almost 2 years
I am learning to use
ExectorService
to poolthreads
and send out tasks. I have a simple program belowimport java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; class Processor implements Runnable { private int id; public Processor(int id) { this.id = id; } public void run() { System.out.println("Starting: " + id); try { Thread.sleep(5000); } catch (InterruptedException e) { System.out.println("sorry, being interupted, good bye!"); System.out.println("Interrupted " + Thread.currentThread().getName()); e.printStackTrace(); } System.out.println("Completed: " + id); } } public class ExecutorExample { public static void main(String[] args) { Boolean isCompleted = false; ExecutorService executor = Executors.newFixedThreadPool(2); for (int i = 0; i < 5; i++) { executor.execute(new Processor(i)); } //executor does not accept any more tasks but the submitted tasks continue executor.shutdown(); System.out.println("All tasks submitted."); try { //wait for the exectutor to terminate normally, which will return true //if timeout happens, returns false, but this does NOT interrupt the threads isCompleted = executor.awaitTermination(100, TimeUnit.SECONDS); //this will interrupt thread it manages. catch the interrupted exception in the threads //If not, threads will run forever and executor will never be able to shutdown. executor.shutdownNow(); } catch (InterruptedException e) { } if (isCompleted) { System.out.println("All tasks completed."); } else { System.out.println("Timeout " + Thread.currentThread().getName()); } } }
It does nothing fancy, but creates two
threads
and submits 5 tasks in total. After eachthread
completes its task, it takes the next one, In the code above, I useexecutor.submit
. I also changed toexecutor.execute
. But I do not see any difference in the output. In what way are thesubmit
andexecute
methods different? This what theAPI
saysMethod submit extends base method Executor.execute(java.lang.Runnable) by creating and returning a Future that can be used to cancel execution and/or wait for completion. Methods invokeAny and invokeAll perform the most commonly useful forms of bulk execution, executing a collection of tasks and then waiting for at least one, or all, to complete. (Class ExecutorCompletionService can be used to write customized variants of these methods.)
But it's not clear to me as what it exactly means?
-
Shanu Gupta almost 6 yearsJust to add-> It can't cancel once the thread has picked up the task. Though it'll interrupt the threading running it.
-
Admin about 5 years
submit
does not "hide" an exception, it throws it wrapped inExecutionException
whenget
is called. The original exception can then be retrieved byExecutionException.getCause()
-
zakmck over 3 yearsNo, the execute() specification says "Executes the given command at some time in the future". So, it's not necessarily started immediately. The difference is that you don't care when it's executed or to check things like a result or completion.
-
Gray about 3 yearsAnother difference is that if the job that is run with
execute(...)
throws an exception, the thread will be killed in the process and possibly then restarted by theExecutorService
. -
Haseeb over 2 yearsPrecise and to the point answer, full marks to @Ravindra