Executors framework (java.util.concurrent.Executor), released with the JDK 5 in package java.util.concurrent is used to run the Runnable objects without creating new threads every time and mostly re-using the already created threads. An ExecutorService is thus very similar to a thread pool. In fact, the implementation of ExecutorService presents in the java.util.concurrent package is a thread pool implementation.
Executor Service Hierarchy
The Executor framework helps to decouple a command submission from command execution.
In the java.util.concurrent package there are three interfaces:
Executor — It is used to submit a new task.
ExecutorService — A sub-interface of Executor that adds methods to manage life cycle of threads used to run the submitted tasks and methods to produce a Future to get a result from an asynchronous computation.
ScheduledExecutorService — A sub-interface of ExecutorService, to execute commands periodically or after a given delay.
This Interface used to submit a new task. Executor is an interface that declares only one method.
A sub-interface of Executor that adds methods to manage the lifecycle of threads used to run the submitted tasks and methods to produce a Future to get a result from an asynchronous computation.
ExecutorService adds a more useful and advanced version method to execute commands, submit.
Passing a Callable to the submit method is possible to get a Future object and use it to retrieve the result of the asynchronous computation.
Additionally, it is possible to shutdown an ExecutorService rejecting submission of new commands. Using the shutdown method all submitted commands will be executed before stopping the ExecutorService, but no new command is accepted. A call to shutdownNow prevents waiting for tasks to be executed and try to stop all currently executing commands.
Since ExecutorService is an interface, you need to its implementations in order to make any use of it. The ExecutorService has the following implementation in the java.util.concurrent package:
Creating an ExecutorService
How you create an ExecutorService depends on the implementation you use. However, you can use the Executors factory class to create ExecutorService instances too.
There are a few different ways to delegate tasks for execution to an ExecutorService:
The execute(Runnable) method takes a java.lang.Runnable object, and executes it asynchronously.
There is no way of obtaining the result of the executed Runnable.
The submit(Runnable) method also takes a Runnable implementation but returns a Future object. This Future object can be used to check if the Runnable as finished executing.
The submit(Callable) method is similar to the submit(Runnable) method except for the type of parameter it takes. The Callable instance is very similar to a Runnable except that its call() method can return a result. The Runnable.run() method cannot return a result.
The Callable's result can be obtained via the Future object returned by the submit(Callable) method.
The above code example will output this:
When you are done using the ExecutorService you should shut it down, so the threads do not keep running.
To terminate the threads inside the ExecutorService you call its shutdown() method. The ExecutorService will not shut down immediately, but it will no longer accept new tasks, and once all threads have finished current tasks, the ExecutorService shuts down. All tasks submitted to the ExecutorService before shutdown() is called, are executed.
If you want to shut down the ExecutorService immediately, you can call the shutdownNow() method. This will attempt to stop all executing tasks right away and skips all submitted but non-processed tasks. There are no guarantees given the executing tasks. Perhaps they stop, perhaps execute until the end. It is a best effort attempt.
A sub-interface of ExecutorService which can be used to execute commands periodically or after a given delay.
The ScheduledExecutorService is used to schedule command executions after a given delay or periodically, it must be used as a replacement for Timer and TimerTask.
It uses the method schedule to run the command after a given delay of time, scheduleAtFixedRate and scheduleWithFixedDelay are used to execute a task periodically.