Java ExecutorService

In this tutorial, we will learn about java.util.concurrent.ExecutorService interface, its features including explanation along with the working examples of it.

java.util.concurrent.ExecutorService

In Java, java.util.concurrent.ExecutorService is an interface that represents an asynchronous task execution framework, providing a simple way to execute tasks concurrently using a thread pool. The ExecutorService manages the creation, scheduling, and execution of the tasks.

Advantages of ExecutorService:

  1. It manages a pool of threads for executing tasks, thereby reducing the overhead of creating and destroying threads for each task.
  2. The tasks submitted to the ExecutorService are executed asynchronously, allowing the application to perform other tasks while the submitted tasks are being executed.
  3. The ExecutorService uses a queue to schedule the tasks for execution. The scheduling algorithm can be customized by providing a custom BlockingQueue implementation.
  4. The ExecutorService provides methods to control the execution of tasks, such as cancelling a task, waiting for the completion of a task, or waiting for all the submitted tasks to complete.
  5. The ExecutorService provides a way to handle exceptions that occur during the execution of a task, allowing the application to handle gracefully for such errors.

ExecutorService example:

In this example, we are assigning 10 tasks to thread pool whose pool size is 3.

CopiedCopy Code
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorServiceExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        for ( int i= 1; i <= 10; i++) {
            executor.submit(new Runnable() {
				@Override
				public void run() {
					System.out.println("Task Executed by : "+Thread.currentThread().getName());
				}
			});
        }
        executor.shutdown();
    }
}

Output :

Task Executed by : pool-1-thread-1
Task Executed by : pool-1-thread-3
Task Executed by : pool-1-thread-2
Task Executed by : pool-1-thread-2
Task Executed by : pool-1-thread-2
Task Executed by : pool-1-thread-2
Task Executed by : pool-1-thread-2
Task Executed by : pool-1-thread-3
Task Executed by : pool-1-thread-1
Task Executed by : pool-1-thread-2

Explanation:

we create a new ExecutorService with a fixed thread pool of 3 threads. We submit 10 tasks, each task printing the name of the thread executing the task. The shutdown() method is called on the executor to shut down the thread pool after all the tasks have been completed.

Executor service example 2:

CopiedCopy Code
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorServiceExample2 {
	public static void main(String[] args) {
		ExecutorService executor = Executors.newFixedThreadPool(5);
		for(int i=1;i<=10;i++) {
			executor.submit(new Tasks(i));
		}
		// This is important otherwise will not be exited after completing task execution
		executor.shutdown();
	}
	static class Tasks implements Runnable {
		public Integer var;
		Tasks(Integer var) {
			this.var = var;
		}
		@Override
		public void run() {
			System.out.println("Task picked by "+ Thread.currentThread().getName()+" var value :"+var);
			try {
				Thread.sleep(100L);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("Task completed by "+ Thread.currentThread().getName());
		}
	}
}

Output :

Task picked by pool-1-thread-1 var value :1
Task picked by pool-1-thread-3 var value :3
Task picked by pool-1-thread-2 var value :2
Task picked by pool-1-thread-4 var value :4
Task picked by pool-1-thread-5 var value :5
Task completed by pool-1-thread-3
Task picked by pool-1-thread-3 var value :6
Task completed by pool-1-thread-5
Task completed by pool-1-thread-2
Task completed by pool-1-thread-4
Task picked by pool-1-thread-2 var value :7
Task picked by pool-1-thread-4 var value :8
Task completed by pool-1-thread-1
Task picked by pool-1-thread-1 var value :10
Task picked by pool-1-thread-5 var value :9
Task completed by pool-1-thread-1
Task completed by pool-1-thread-5
Task completed by pool-1-thread-4
Task completed by pool-1-thread-2
Task completed by pool-1-thread-3

Explanation:

In the above example, we have submitted 10Tasks for 5 threads of a pool, in the computation method we have printed what thread picked the task and completed the task. The above example guarantees the resource utilization like CPU although if you submit 100 tasks unlike the java.lang.Thread (or) normal threads.

Conclusion:

In this tutorial, we have covered ExecutorService, and its features along with the working examples of it.