Executors and ExecutorService

In Java, the Executor and ExecutorService interfaces provide a framework for managing threads and asynchronous tasks. These interfaces are part of the java.util.concurrent package.

Executor Interface

The Executor interface provides a simple way to decouple task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc. It has a single method:

public interface Executor {
    void execute(Runnable command);
}Code language: PHP (php)

Basic example using the Executor interface:

//SimpleExecutorDemo.java
import java.util.concurrent.Executor;
public class SimpleExecutorDemo {
    public static void main(String[] args) {
        Executor executor = new Executor() {
            @Override
            public void execute(Runnable command) {
                new Thread(command).start();
            }
        };
        executor.execute(() -> System.out.println("Task executed in a separate thread"));
    }
}

/*

C:\>javac SimpleExecutorDemo.java

C:\>java SimpleExecutorDemo
Task executed in a separate thread

*/

In this example, the execute method submits a Runnable task to be executed by creating a new thread for each task.

ExecutorService Interface

ExecutorService extends Executor and adds lifecycle management methods for shutting down the executor and methods for tracking the progress of tasks.

public interface ExecutorService extends Executor {
    void shutdown();
    List<Runnable> shutdownNow();
    boolean isShutdown();
    boolean isTerminated();
    boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;
    <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;
    <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException;
}
Code language: HTML, XML (xml)

Program

An example using the ExecutorService.

//ExecutorServiceDemo.java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ExecutorServiceDemo {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(() -> {
            System.out.println("Task 1 executed in thread: " + Thread.currentThread().getName());
        });
        executorService.submit(() -> {
            System.out.println("Task 2 executed in thread: " + Thread.currentThread().getName());
        });
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(800, TimeUnit.MILLISECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
        }
    }
}

/*

C:\>javac ExecutorServiceDemo.java

C:\>java ExecutorServiceDemo
Task 1 executed in thread: pool-1-thread-1
Task 2 executed in thread: pool-1-thread-2

*/

In this example, Executors.newFixedThreadPool(2) creates a thread pool with 2 threads. The submit method is used to submit tasks for execution. The shutdown method initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. The awaitTermination method waits for all tasks to complete or for a timeout to occur before shutting down.

Executor and ExecutorService  helps to  manage and control thread execution, making it easier to develop scalable and concurrent applications.

Scroll to Top