Back to blog
Nov 20, 2023
3 min read

Executor Service with Thread in Java

The ExecutorService interface in Java provides a powerful mechanism for managing threads and executing tasks asynchronously.

It is part of the java.util.concurrent package and is commonly used in multithreaded applications to improve performance and resource utilization. Below, we’ll explore the Executor Service in more detail along with a comprehensive example.

Executor Service Overview

The Executor Service abstracts the complexity of managing threads by providing a pool of worker threads that can execute tasks concurrently. It offers several advantages over directly working with threads, including:

  • Efficient resource management: Executor Service manages thread creation, pooling, and reusing, reducing the overhead of creating new threads for each task.
  • Task queuing: Tasks submitted to the Executor Service are queued and executed by available threads in the thread pool, preventing resource exhaustion.
  • Thread lifecycle management: Executor Service handles the lifecycle of worker threads, including creation, termination, and thread safety.

Executor Service Example

  • Let’s demonstrate how to use the Executor Service with a simple example:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorServiceExample {

    public static void main(String[] args) {
        // Create an executor service with a fixed-size thread pool
        ExecutorService executor = Executors.newFixedThreadPool(5);

        // Define a task as a Runnable
        Runnable task = () -> {
            System.out.println("Executing task on thread: " + Thread.currentThread().getName());
        };

        // Submit the task to the executor service
        executor.submit(task);

        // Shutdown the executor service
        executor.shutdown();
    }
}


Explanation

  • We create an instance of ExecutorService using the Executors.newFixedThreadPool() method, specifying a fixed-size thread pool with 5 threads.
  • A task is defined as a Runnable object, representing the work to be executed asynchronously.
  • The task is submitted to the executor service using the submit() method, which adds it to the task queue for execution.
  • Finally, we shut down the executor service using the shutdown() method, which gracefully terminates the threads after executing all pending tasks.

Conclusion

The Java Executor Service simplifies concurrent programming by providing a high-level abstraction for managing threads and executing tasks asynchronously. It offers flexibility, scalability, and efficiency, making it an essential tool for building multithreaded applications.