Search code examples
javamultithreadingexecutorservicejava.util.concurrent

ExecutorService JVM doesn't terminate


I don't understand why I have to call executorService.shutdown() explicitly to terminate executorService. If I do not call shutdown() then the JVM does not terminate on its own.

What is wrong with my program or what concept am I missing?

public class ExecutorServiceExample {

    public static class Task1 implements Runnable {

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("Message from Task1 :"
                    + Thread.currentThread().getName());
        }

    }

    public static class Task2 implements Runnable {

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Message from Task2 :"
                    + Thread.currentThread().getName());
        }

    }

    public static class Task3 implements Runnable {

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Message from Task3 :"
                    + Thread.currentThread().getName());
        }

    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        Future future1 = executorService.submit(new Task1());
        Future future2 = executorService.submit(new Task2());
        Future future3 = executorService.submit(new Task3());


    }

}

Output:

Message from Task2 :pool-1-thread-2

Message from Task1 :pool-1-thread-1

Message from Task3 :pool-1-thread-3

The JVM is still alive. If I will call shutdown() then only JVM would die.


Solution

  • According to Thread javadoc:

    The Java Virtual Machine continues to execute threads until either of the following occurs:

    • The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
    • All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.

    Your executor creates non-daemon threads which prevent your JVM from shutting down. Threads created by executors are usually pooled to run more than one task submitted to the executor - often this is a performance optimisation to reuse threads so they run more then one task (as creating new thread is an expensive operation). Depending on the implementation and configuration of the executor (e.g. see ThreadPoolExecutor doc, especially keepalive configuration) it might keep the threads running forever or terminate when they are unused for some time.

    You must either call shutdown on your executor or create it with a custom ThreadFactory (e.g. using Executors.newFixedThreadPool(int, ThreadFactory)) where that thread factory will configure new threads as daemon ones.