Java ExecutorService
Java ExecutorService is an interface that provides methods to execute asynchronous tasks, check the results of those tasks, and shutdown those running tasks when needed.
Java ExecutorService is useful when we want to run multiple tasks concurrently in the background. The ExecutorService provides a pool of threads for processing tasks.
Creating ExecutorService
We can use the Executors factory class from the java.util.concurrent package to create instances of ExecutorService. The Executors class provides several factory methods for creating instances of ExecutorService. How you want to create an instance of ExecutorService depends on what you want your code to do.
Here are some examples of creating instances of ExecutorService:
ExecutorService fixedPoolExecutor = Executors.newFixedThreadPool(10);
ExecutorService chachedPoolExecutor = Executors.newCachedThreadPool();
ExecutorService singleExecutor = Executors.newSingleThreadExecutor();
ExecutorService scheduledPoolExecutor = Executors.newScheduledThreadPool(10);
ExecutorService Methods to Run Tasks
The following are the methods for delegating task to ExecutorService:
- execute(Runnable command) - Executes a task in a new thread, in a new pooled thread, or in the calling thread.
Example:
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println("My task here");
}
});
executorService.shutdown();
Example:
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future future = executorService.submit(new Runnable() {
@Override
public void run() {
System.out.println("My task here");
}
});
future.get(); // returns null on successful completion
executorService.shutdown();
Example:
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future future = executorService.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
System.out.println("Asynchronous task");
return "You can return your object here";
}
});
future.get();
executorService.shutdown();
Example:
ExecutorService executorService = Executors.newFixedThreadPool(4);
List<Callable<String>> callableTaskList = new ArrayList<>();
callableTaskList.add(new Callable<String>() {
@Override
public String call() throws Exception {
return "Asynchronous task 1";
}
});
callableTaskList.add(new Callable<String>() {
@Override
public String call() throws Exception {
return "Asynchronous task 2";
}
});
callableTaskList.add(new Callable<String>() {
@Override
public String call() throws Exception {
return "Asynchronous task 3";
}
});
callableTaskList.add(new Callable<String>() {
@Override
public String call() throws Exception {
return "Asynchronous task 4";
}
});
List<Future<String>> futureList = executorService.invokeAll(callableTaskList);
for (Future<String> future : futureList) {
future.get();
}
executorService.shutdown();
Example:
ExecutorService executorService = Executors.newFixedThreadPool(4);
List<Callable<String>> callableTaskList = new ArrayList<>();
callableTaskList.add(new Callable<String>() {
@Override
public String call() throws Exception {
return "Asynchronous task 1";
}
});
callableTaskList.add(new Callable<String>() {
@Override
public String call() throws Exception {
return "Asynchronous task 2";
}
});
callableTaskList.add(new Callable<String>() {
@Override
public String call() throws Exception {
return "Asynchronous task 3";
}
});
callableTaskList.add(new Callable<String>() {
@Override
public String call() throws Exception {
return "Asynchronous task 4";
}
});
String result = executorService.invokeAny(callableTaskList);
executorService.shutdown();
Cancel Task
A running task can be cancelled by calling the cancel() method on the Future object. The cancel attempt will not work if the task has already been completed or cancelled.
future.cancel(true);
ExecutorService Shutdown
Following are some of the methods to shutdown ExecutorService:
- shutdown() - This method intiates an orderly shutdown and does not wait for the previously submitted tasks to complete.
executorService.shutdown();
executorService.shutdownNow();
executorService.shutdown();
executorService.awaitTermination(60, TimeUnit.SECONDS);