Week 82 — What is an `ExecutorService` and how can it be used?

Question of the Week #82
What is an ExecutorService and how can it be used?
5 Replies
Eric McIntyre
Eric McIntyre5mo ago
ExecutorService provides a mechanism to execute code asynchronously, typically using a thread pool. This can be done using the ExecutorService#execute method where the code to execute is supplied as a Runnable:
ExecutorService executor = Executors.newCachedThreadPool();//create an ExecutorService that creates one thread for every task and reuses these threads
executor.execute(() -> {
System.out.println("This runs in thread " + Thread.currentThread().getName());
});
ExecutorService executor = Executors.newCachedThreadPool();//create an ExecutorService that creates one thread for every task and reuses these threads
executor.execute(() -> {
System.out.println("This runs in thread " + Thread.currentThread().getName());
});
It also provides submit methods that return a Future representing the task being executed and allow obtaining the result.
Future<String> future = executor.submit(() -> {
//do some work
return "Hello World";
});
//something else could be done here
System.out.println(future.isDone());//check if the task is done already
System.out.println(future.get());//wait for it to complete and get the result
Future<String> future = executor.submit(() -> {
//do some work
return "Hello World";
});
//something else could be done here
System.out.println(future.isDone());//check if the task is done already
System.out.println(future.get());//wait for it to complete and get the result
The class Executors provides factory methods for creating different ExecutorServices. For example, newCachedThreadPool() creates a new ExecutorService where new threads are created for each task if all its threads are currently working and reuses old threads where the tasks have completed. Similarly, it is possible to create an ExecutorService with a fixed amount of threads using newFixedThreadPool(numberOfThreads) or obtain one that creates a virtual thread for each task using newVirtualThreadPerTaskExecutor().
Eric McIntyre
Eric McIntyre5mo ago
Apart from executing tasks, ExecutorService also provides shutdown() and shutdownNow() methods. The shutdown() method makes sure no further tasks can be submitted while shutdownNow() also interrupts currently running tasks. In order to wait for all the tasks to complete after calling shutdown() or shutdownNow(), one can use the awaitTermination method.
executor.shutdown();//make sure no new threads are submitted
boolean completed = executor.awaitTermination(10, TimeUnit.SECONDS);//wait up to 10 seconds for the tasks to complete
if(!completed) {
executor.shutdownNow();//also interrupt the threads
completed = executor.awaitTermination(5, TimeUnit.SECONDS);//wait 5 more seconds
}
if(!completed) {
System.err.println("Executor did not terminate within the expected time");
}
executor.shutdown();//make sure no new threads are submitted
boolean completed = executor.awaitTermination(10, TimeUnit.SECONDS);//wait up to 10 seconds for the tasks to complete
if(!completed) {
executor.shutdownNow();//also interrupt the threads
completed = executor.awaitTermination(5, TimeUnit.SECONDS);//wait 5 more seconds
}
if(!completed) {
System.err.println("Executor did not terminate within the expected time");
}
📖 Sample answer from dan1st
Eric McIntyre
Eric McIntyre5mo ago
An ExecutorService is an interface which allows us to excute tasks on threads asynchronously . It helps in maintaining a pool of threads and assign them a task.
Submission from justshubham07
Eric McIntyre
Eric McIntyre5mo ago
ExecutorService is part of Java's concurrent utility classes for multi-threaded programming. It is a specialization of Executor, which simply provides a generic mechanism for submitting Runnable tasks to be executed. It is up to each implementation to decide how to execute the tasks. On top of the basic task execution functionality, the ExecutorService provides methods for submitting Runnables and Callables, and monitoring or controlling the progression of those tasks via the returned Futures. In addition to submitting tasks one at a time, the service provides convenience methods for submitting tasks in bulk and waiting for all or the first one to complete. The remaining methods on the service provide a means of querying and controlling the lifecycle of the service, i.e. shutdown. The JDK provides multiple implementations for the ExecutorService, each with a different execution strategy or additional functionality to support concurrent task execution. See the implementors of ExecutorService for details.
Eric McIntyre
Eric McIntyre5mo ago
The ExecutorService should be used in the place of raw Threads when implementing something like a work queue, where multiple tasks need to be executed in parallel or without tying up the current thread. The service implementations simplify the thread management, especially when it comes to monitoring the status of the tasks and shutting down gracefully (which can cause a process to "hang" if not implemented correctly).
Submission from dangerously_casual
Want results from more Discord servers?
Add your server