# Executor Service

In 
Published 2022-12-03

This tutorial explains how to use the Executor Service in Java.

The Java ExecutorService is the interface which allows us to execute tasks on threads asynchronously. It defines a pool of threads to be used.

How you create an ExecutorService depends on the implementation you use.

Examples:
// It create a pool for a single thread  
ExecutorService es1 = Executors.newSingleThreadExecutor();

// It create a thread pool with maximum 10 threads
ExecutorService es2 = Executors.newFixedThreadPool(10);

// It create a thread pool with maximum 10 threads. The tasks could be scheduled using a pattern.
ScheduledExecutorService es3 = Executors.newScheduledThreadPool(10);

Take a look at the following example and read carefully the comment in the code.

package com.exampe.java;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) throws InterruptedException, ExecutionException {

		SpringApplication.run(DemoApplication.class, args);

		System.out.println("--------------------------------------------");
		Runnable task1 = () -> {
			for (int i = 1; i <= 5; i++) {
				System.out.println("Task #1 is running");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					throw new RuntimeException(e);
				}
			}

		};

		Callable<Integer> task2 = () -> {
			for (int i = 1; i <= 5; i++) {
				System.out.println("Task #2 is running");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					throw new RuntimeException(e);
				}
			}
			return 10;
		};

		Callable<Integer> task3 = () -> {
			for (int i = 1; i <= 5; i++) {
				System.out.println("Task #3 is running");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					throw new RuntimeException(e);
				}
			}
			return 10;
		};

		ExecutorService es1 = Executors.newFixedThreadPool(10);

		// Run a task without returned value.
		es1.execute(task1);

		// Run a task. The task has a result kept in the future object
		Future f1 = es1.submit(task2);

		//Print the result of the task
		System.out.println("f1= "+f1.get());

		List<Callable<Integer>> taskList = new ArrayList<>();
		taskList.add(task2);
		taskList.add(task3);

		// The task2 & task3 will run simultaneously. The first returned resul will be taken
		// by the "result" variable.
		Integer result = es1.invokeAny(taskList);
		System.out.println("result="+result);

		// Run in parallel a list of tasks and keep the result returned by each of them
		// In this case I print the result of the first task in the list ("task2")
		List<Future<Integer>> result2 = es1.invokeAll(taskList);
		System.out.println("result2="+result2.get(0).get());

		// Stop the Executor Service
		es1.shutdown();
		System.out.println("--------------------------------------------");
	}
}