Java ExecutorService Examples To Create Thread Pool

1. Introduction


Java ExecutorService is a framework which simplifies the creation of ThreadPool in Java and allows the execution of the task concurrently in asynchronous mode.  It accepts both Runnable and Callable tasks. Here you will learn how to use ExecutorService to create a ThreadPool and dispatch the tasks to execute concurrently.

2. Java ExecutorService Implementations


As I mentioned in the introduction that Java ExecutorService is used to create Thread Pool, the implementation provided for ExecutorService interface is, in fact, a Thread Pool implementation. The ExecutorService has the following implementation in the java.util.concurrent package:

3. Creating Java ExecutorService


How to Create or Instantiate ExecutorService depends on the implementation that to use. Below are the 2 different way to create ExecutorService. Easiest of these 2 ways is using Executors factory method.

  • Creating with Executors factory methods
  • Directly creating an ExecutorService

3.1. Creating with Executors factory methods

Below java example shows how to create ExecutorService with Executors factory methods


ExecutorService executorService1 = Executors.newSingleThreadExecutor();
ExecutorService executorService2 = Executors.newFixedThreadPool(15);
ExecutorService executorService3 = Executors.newScheduledThreadPool(15);

 

The are several other factory methods to create ExecutorService that meet specific use cases. To find the best method for your needs, refer to Oracle’s official documentation.

3.2. Directly creating an ExecutorService

ExecutorService is an interface, an instance of any its implementations can be used. There are several implementations to choose from in the java.util.concurrent package or you can also create your own.

For example, the ThreadPoolExecutor class has a few constructors which can be used to configure an executor service and its internal pool.


ExecutorService executorService = 
  new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,   
  new LinkedBlockingQueue());

4. ExecutorService Usage


ExecutorService can execute Runnable and Callable tasks. There are a few different ways to delegate tasks for execution to an ExecutorService.

  • execute(Runnable)
  • submit(Runnable)
  • submit(Callable)
  • invokeAny()
  • invokeAll()

We will also take a look at each of these methods in the following sections.

4.1. execute(Runnable)

The execute() method returns void, and it doesn’t give any possibility to get the result of task’s execution or to check the task’s status (is it running or executed). The Java ExecutorService’s execute(Runnable) method takes a java.lang.Runnable object, and executes it asynchronously. Here is an example of executing a Runnable with an ExecutorService:

 

/****************************************************************************************
 * Created on 06-2019 Copyright(c) https://kodehelp.com All Rights Reserved.
 ****************************************************************************************/
package com.kodehelp.java.thread;

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

/**
 * Created by https://kodehelp.com
 * Date: 06/23/2019
 */
public class ExecuteRunnableTaskExample {

	
	public static void main(String[] args) {
		
		//Create thread with ExecutorService's newSingleThreadExecutor method
		ExecutorService executor = Executors.newSingleThreadExecutor();
		
		//Notice that Java 8 lambda expressions are used here instead of 
		//anonymous inner classes.
		executor.execute(() -> System.out.println("I'm Runnable task using Java 8+."));
		
		//Before Java 8, you need to pass anonymous inner class as below
		executor.execute(new Runnable() {
			public void run() {
		        System.out.println("I'm Runnable task before Java 8.");
		    }
		});
		

	}

}

4.2. submit(Runnable)

The Java ExecutorService submit(Runnable) method also takes a Runnable implementation, but returns a Future object. This Future object is used to check if the Runnable has finished executing. Here is a Java ExecutorService submit() example:


/****************************************************************************************
 * Created on 06-2019 Copyright(c) https://kodehelp.com All Rights Reserved.
 ****************************************************************************************/
package com.kodehelp.java.thread;

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

/**
 * Created by https://kodehelp.com
 * Date: 06/23/2019
 */
public class ExecuteRunnableTaskExample {

	
	public static void main(String[] args) {
		//Create threads with ExecutorService's newFixedThreadPool method
		ExecutorService executor = Executors.newFixedThreadPool(5);
		try {
			
			
			//Notice that Java 8 lambda expressions are used here instead of 
			//anonymous inner classes.
			Future<?> future1 = executor.submit(() -> {
				System.out.println("I'm Runnable task using Java 8+.");
			});
			
			System.out.println(future1.get());            
			
			
			//Before Java 8, you need to pass anonymous inner class as below
			Future<?> future2 = executor.submit(new Runnable() {
				public void run() {
			        System.out.println("I'm Runnable task before Java 8.");
			    }
			});
			
			System.out.println(future2.get());  
		}catch (InterruptedException e) {// thread was interrupted
            e.printStackTrace();
        } catch (ExecutionException e) {// thread threw an exception
            e.printStackTrace();
        } finally {

            // shut down the executor manually
            executor.shutdown();

        }

	}

}

4.3. submit(Callable)

The Java ExecutorService submit(Callable) method is similar to the submit(Runnable) method except it takes a Java Callable instead of a Runnable. The Callable’s result can be obtained via the Java Future object returned by the submit(Callable)method. Here is an ExecutorService Callable example:


/****************************************************************************************
 * Created on 06-2019 Copyright(c) https://kodehelp.com All Rights Reserved.
 ****************************************************************************************/
package com.kodehelp.java.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Created by https://kodehelp.com
 * Date: 06/23/2019
 */
public class ExecuteCallableTaskExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//Create threads with ExecutorService's newFixedThreadPool method
		ExecutorService executor = Executors.newFixedThreadPool(5);
		try {
			//Notice that Java 8 lambda expressions are used here instead of 
			//anonymous inner classes.
			Future<?> future1 = executor.submit(() -> {
	            System.out.println("I'm Callable task.");
	            return 2 + 2;
	        });
			
			System.out.println(future1.get());            
			
			//Before Java 8, you need to pass anonymous inner class as below
			Future<?> future2 = executor.submit(new Callable() {
				public Integer call() {
			        System.out.println("I'm Callable task before Java 8.");
			        return 2 + 2;
			    }
			});
			
			System.out.println(future2.get());  
		}catch (InterruptedException e) {// thread was interrupted
            e.printStackTrace();
        } catch (ExecutionException e) {// thread threw an exception
            e.printStackTrace();
        } finally {

            // shut down the executor manually
            executor.shutdown();

        }

	}

}

4.3. invokeAny()

The invokeAny() method takes a collection of Callable objects, or sub interfaces of Callable. Invoking this method does not return a Future, but returns the result of one of the Callable objects. You will have no guarantee about which of the Callable’s results you get. Just one of the ones that finish. If one of the tasks complete or throws an exception, the rest of the Callable’s are cancelled. Here is the Java ExecutorService example to submit task using invokeAny():


/****************************************************************************************
 * Created on 06-2019 Copyright(c) https://kodehelp.com All Rights Reserved.
 ****************************************************************************************/
package com.kodehelp.java.thread;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by https://kodehelp.com
 * Date: 06/23/2019
 */
public class InvokeAnyExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//Create threads with ExecutorService's newFixedThreadPool method
		ExecutorService executor = Executors.newFixedThreadPool(2);
		try {
			//Notice that Java 8 lambda expressions are used here instead of 
			//anonymous inner classes.
			List<Callable> listOfCallable = Arrays.asList(
	                () -> 1,
	                () -> 2,
	                () -> 3);
			
			Integer result = executor.invokeAny(listOfCallable);
			
			System.out.println(result);            
			
		}catch (InterruptedException e) {// thread was interrupted
            e.printStackTrace();
        } catch (ExecutionException e) {// thread threw an exception
            e.printStackTrace();
        } finally {

            // shut down the executor manually
            executor.shutdown();

        }

	}

}

4.5. invokeAll()

The invokeAll() method invokes all of the Callable objects you pass to it in the collection passed as parameter. The invokeAll() returns a list of Future objects via which you can obtain the results of the executions of each Callable.

Keep in mind that a task might finish due to an exception, so it may not have “succeeded”. There is no way on a Future to tell the difference.

Here is the Java ExecutorService example for invokeAll() :


/****************************************************************************************
 * Created on 06-2019 Copyright(c) https://kodehelp.com All Rights Reserved.
 ****************************************************************************************/
package com.kodehelp.java.thread;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Created by https://kodehelp.com
 * Date: 06/23/2019
 */
public class InvokeAllExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//Create threads with ExecutorService's newFixedThreadPool method
		ExecutorService executor = Executors.newFixedThreadPool(2);
		try {
			//Notice that Java 8 lambda expressions are used here instead of 
			//anonymous inner classes.
			List<Callable> listOfCallable = Arrays.asList(
	                () -> 1,
	                () -> 2,
	                () -> 3);
			
			List<Future> futures = executor.invokeAll(listOfCallable);
			
			for(Future future : futures){
			    System.out.println("future.get = " + future.get());
			}
			
		}catch (InterruptedException e) {// thread was interrupted
            e.printStackTrace();
        } catch (ExecutionException e) {// thread threw an exception
            e.printStackTrace();
        } finally {

            // shut down the executor manually
            executor.shutdown();

        }

	}

}

References:

Please Post Your Comments & Reviews

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.