ExecutorService to Manage Executor Lifecycle in Java

The interface ExecutorService extends Executor and provides methods to manage the lifecycle of an Executor like:

  • means to termination of an Executor,

  • methods that can produce a Future etc.

Note: A Future object can be used for tracking the progress of one or more asynchronous tasks. 

 

Important Lifecycle Methods of ExecutorService

  • Method submit extends base method Executor.execute(java.lang.Runnable) by creating and returning a Future that can be used to cancel execution and/or wait for completion. 

  • Methods invokeAny and invokeAll execute a collection of tasks and then wait for at least one, or all, to complete, respectively.  

  • An ExecutorService can be shut down, which will cause it to reject new tasks. The shutdown() method will allow previously submitted tasks to execute before terminating, while the shutdownNow() method prevents waiting tasks from starting and attempts to even stop currently executing tasks. Tasks submitted to an ExecutorService after it has been shut down are handled by the rejected execution handler, which  might  discard  the  task  or  might  cause  execute  to  throw  the  unchecked RejectedExecutionException.  

  • Once  all  tasks  have  completed, the  ExecutorService  transitions  to  the  terminated state. The awaitTermination(long timeout, TimeUnit unit) method blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted.

  • The isShutdown() and isTerminated() methods returns true if this executor has been shut down or if  executor is in terminated state, respectively.

 

Example – ExecutorServiceDemo.java

import java.util.Date;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

 

public class ExecutorServiceDemo {

  public void execDemo(final ExecutorService exec) {

    for (int i = 0; i < 5; i++) {

      Runnable task = new Runnable() {

        @Override

        public void run() {

          try {

            System.out.println("Started " + 

              Thread.currentThread() + " at "

                + new Date());

 

            Thread.sleep(1000);

 

            System.out.println("Exiting " + 

              Thread.currentThread() + " at "

                + new Date());

          } catch (InterruptedException e) {

            e.printStackTrace();

          }

        }

      };

      exec.execute(task);

    }

 

    System.out.println("Before calling shutdown. Is shutdown="

        + exec.isShutdown());

    exec.shutdown();

    System.out.println("After calling shutdown. Is shutdown="

        + exec.isShutdown());

  }

 

  public static void main(String[] args) {

    ExecutorServiceDemo eD = new ExecutorServiceDemo();

    eD.execDemo(Executors.newFixedThreadPool(2));

  }

}

Here we called shutdown() after submitting all tasks and hence isShutDown() returns true, but submitted tasks are completed. 

OUTPUT

Before calling shutdown. Is shutdown=false

After calling shutdown. Is shutdown=true

Started Thread[pool-1-thread-2,5,main] at Tue Jul 09 15:05:31 IST 2013

Started Thread[pool-1-thread-1,5,main] at Tue Jul 09 15:05:31 IST 2013

Exiting Thread[pool-1-thread-1,5,main] at Tue Jul 09 15:05:36 IST 2013

Started Thread[pool-1-thread-1,5,main] at Tue Jul 09 15:05:36 IST 2013

 

Case 1: Using shutdownNow instead of shutdown()

Replace exec.shutdown(); with exec.shutdownNow();

Here shutdownNow() will try to stop even submitted tasks by interrupting them and might result in an InterruptedException.

OUTPUT

Before calling shutdown. Is shutdown=false

After calling shutdown. Is shutdown=true

Started Thread[pool-1-thread-2,5,main] at Tue Jul 09 15:22:05 IST 2013

Started Thread[pool-1-thread-1,5,main] at Tue Jul 09 15:22:05 IST 2013

java.lang.InterruptedException: sleep interrupted

        …

java.lang.InterruptedException: sleep interrupted

        …

 

Case 2: Calling exec.shutdown(); and submitting tasks

Remove the exec.shutdownNow(); from current place and have an exec.shutdown() inside the for loop just before the end of loop.

OUTPUT

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task GenericExecutorDemo$1@7f8a8bfa rejected from java.util.concurrent.ThreadPoolExecutor@60ec0b80[Shutting down, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]

        …

Started Thread[pool-1-thread-1,5,main] at Tue Jul 09 15:25:18 IST 2013

Exiting Thread[pool-1-thread-1,5,main] at Tue Jul 09 15:25:23 IST 2013

 

Case 3: Calling exec.shutdownNow(); and submitting tasks

Replace exec.shutdown(); with exec.shutdownNow();

Submitting tasks after shutdown are handled by rejected execution handler and might result in RejectedExecutionException. Here shutdownNow() will also try to stop the already submitted tasks by interrupting them and might result in an InterruptedException.

OUTPUT

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task ExecutorServiceDemo$1@143c8b3 rejected from java.util.concurrent.ThreadPoolExecutor

...

java.lang.InterruptedException: sleep interrupted

...

Search the Web

Custom Search

Searches whole web. Use the search in the right sidebar to search only within javajee.com!!!