ExecutorService Usage
The ExecutorService in Java is a higher-level replacement for managing threads and tasks, providing a framework for concurrent task execution. It abstracts away the complexities of creating and managing threads directly. There are a several ways to delegate tasks for execution to an ExecutorService.
Creating an ExecutorService
ExecutorServiceRefer to the ExecutorService Implementationsfor more details.
// Fixed Thread Pool
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
// Cached Thread Pool
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
// Single Thread Executor
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
// Scheduled Thread Pool
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);Submitting Tasks to ExecutorService
ExecutorServiceexecute(Runnable command):
execute(Runnable command):Executes the given command at some point in the future asynchronously.
No result is returned, and exceptions are not captured.
Example:
submit(Runnable command):
submit(Runnable command):The Java
ExecutorServicesubmit(Runnable)method also takes aRunnableimplementation, but returns aFutureobject. ThisFutureobject can be used to check if theRunnablehas finished executing.
Example:
submit(Callable<T> task):
submit(Callable<T> task):Submits a
Callabletask for execution and returns aFuturerepresenting the task’s result.
Example:
invokeAll(Collection<? extends Callable<T>> tasks):
invokeAll(Collection<? extends Callable<T>> tasks):Executes a collection of
Callabletasks and returns a list ofFutureobjects.The
invokeAll()method invokes all of theCallableobjects passed to it in the collection passed as parameter. TheinvokeAll()returns a list ofFutureobjects via which we can obtain the results of the executions of eachCallable. A task might finish due to an exception, so it may not have succeeded. There is no way on aFutureto tell the difference.If an exception occurs during the execution of one of the
Callabletasks, that exception will be captured and stored within the correspondingFutureobject.
Example:
Exception During Task Execution:
If an exception occurs during the execution of one of the
Callabletasks, that exception will be captured and stored within the correspondingFutureobject.The
invokeAll()method itself will not throw an exception in this case. Instead, you will need to check eachFuturefor exceptions by callingfuture.get()on them.
InterruptedException:
The
invokeAll()method may throw anInterruptedExceptionif the calling thread is interrupted while waiting for the tasks to complete.This exception needs to be handled explicitly. When this happens, none of the results will be available, and the thread's interrupted status will be set.
Rejection During Task Submission:
invokeAll()will not submit tasks one by one; it submits all tasks as a batch. If theExecutorServiceis shutting down or if its task queue is full, it will reject all tasks and throw aRejectedExecutionException. However,invokeAll()is designed to handle such situations internally, and this is generally not a concern unless we are dealing with a custom implementation.
invokeAny(Collection<? extends Callable<T>> tasks):
invokeAny(Collection<? extends Callable<T>> tasks):Executes the given tasks and returns the result of one that successfully completes (or throws an exception if none complete).
The
invokeAny()method takes a collection ofCallableobjects, or subinterfaces ofCallable. Invoking this method does not return aFuture, but returns the result of one of theCallableobjects. We have no guarantee about which of theCallable's results we will get. Just one of the ones that finish. If one Callable finishes, so that a result is returned frominvokeAny(), then the rest of the Callable instances are cancelled. If one of the tasks complete (or throws an exception), the rest of theCallable's are cancelled.
Example:
cancel()
cancel()We can cancel a task (Runnable or Callable) submitted to a Java ExecutorService by calling the cancel() method on the Future returned when the task is submitted. Cancelling the task is only possible if the task has not yet started executing.
Managing ExecutorService Lifecycle
Shutting Down:
It’s essential to shut down the
ExecutorServiceto free resources when tasks are no longer needed.shutdown(): Initiates an orderly shutdown where previously submitted tasks are executed, but no new tasks will be accepted.shutdownNow(): Attempts to stop all actively executing tasks and halts the processing of waiting tasks.
Example:
Checking for Termination:
isShutdown(): Returnstrueif theExecutorServicehas been shut down.isTerminated(): Returnstrueif all tasks have completed following shutdown.
Example:
Last updated