ExecutorService is a framework for asynchronous execution in java. By using ExecutorService you can easily create a multi-threaded execution environment.
This article will explain in detail the specific use of ExecutorService.
Creating an ExecutorService
Generally speaking, there are two ways to create an ExecutorService.
The first way is to use the factory class methods in Executors, for example.
In addition to the newFixedThreadPool method, Executors contains a number of methods to create an ExecutorService.
The second method is to create an ExecutorService directly, because ExecutorService is an interface, we need to instantiate an implementation of ExecutorService.
Here we use ThreadPoolExecutor as an example.
Allocate Tasks for ExecutorService
ExecutorService can execute Runnable and Callable tasks, where Runnable has no return value and Callable has a return value. Let’s look at the use of each of the two cases.
Assigning a task to an ExecutorService can be done by calling the methods execute(), submit(), invokeAny(), invokeAll().
execute() returns void, which is used to submit a Runnable task.
submit() returns Future, which can submit a Runnable task, or a Callable task. There are two methods for submitting a Runnable.
The first method returns the result when it is passed in. the second method returns null.
Look again at the use of callable.
invokeAny() passes a list of tasks to the executorService and returns one of the successfully returned results.
invokeAll() passes a list of tasks to the executorService and returns the results of all successful executions.
The ExecutorService will not automatically close if the tasks in the ExecutorService have finished running. It will wait to receive new tasks. If we need to shut down the ExecutorService, we need to call shutdown() or shutdownNow() method.
shutdown() will destroy the ExecutorService immediately, it will make the ExecutorServic stop receiving new tasks and wait until all existing tasks are executed before destroying it.
shutdownNow() does not guarantee that all tasks have been executed, it returns a list of unexecuted tasks:
The best shutdown method recommended by oracle is to use it with awaitTermination:
Stop receiving tasks first, then wait for a certain amount of time for all tasks to finish executing, and if the given time is exceeded, end the task immediately.
submit() and invokeAll() both return Future objects. We’ve talked about Future in detail in previous articles. Here’s just a list of how to use.
ScheduledExecutorService provides us with a mechanism to execute tasks at regular intervals.
We create the ScheduledExecutorService like this.
executorService’s schedule method, which can be passed to either Runnable or Callable: `` `
There are two other more similar methods.
The difference between the two is that the former’s period is calculated with the task start time and the latter is calculated with the task end time.
ExecutorService and Fork/Join
java 7 introduces the Fork/Join framework. So what is the difference between the two?
ExecutorService allows the user to control the generated threads themselves, providing more granular control over threads. Fork/Join, on the other hand, is designed to allow tasks to be executed more quickly.