5
votes

I am trying to understand multi-threading in Java. I have written the following java program to test thread pool.

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

        for( int i = 0; i < 3; i++ )
        {
            executorService.submit(new Task(i+1));
        }
        executorService.shutdown();                     

    }

    public static class Task implements Runnable
    {
        private int taskId;

        public Task(int id)
        {
            taskId = id;
        }

        @Override
        public void run() {
            System.out.println("Executing task " + taskId + " performed by " + Thread.currentThread().getName() );
            try
            {
                Thread.sleep(3000);
            }
            catch(InterruptedException interruptEx)
            {
                System.out.println(Thread.currentThread().getName() + " got interrupted ");
            }
            System.out.println("Finished executing task " + taskId );
        }
    }
}

The main thread creates executor which creates 5 threads and I have submitted only 3 tasks. After that I am shutting down the executor. When I run the code, the main thread finishes before the child threads. In this case, does JVM takes care of the child threads? Also I have created a thread pool with 5 threads, but submitted only 3 tasks. Will the remaining 2 threads are terminated when the main thread exits?

What actually happens when the executor service is shutdown?

4

4 Answers

4
votes

From the doc of ExecutorService#shutdown():

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.

This means that all the Jobs you submitted to the Executor will finish on their own time without interrupting or "hurrying" them, and the executor will finish up the worker threads properly, but neither will the service accept new Jobs, nor will it terminate instantly.

Compare ExecutorService#shutdownNow(), which will try to terminate as quickly as possible.

3
votes

The Worker threads that the executor creates are inner classes that have a reference back to the executor itself. (They need it to be able to see the queue, runstate, etc!) Running threads are not garbage collected, so with each Thread in the pool having that reference, they will keep the executor alive until all threads are dead. If you don't manually do something to stop the threads, they will keep running forever and your JVM will never shut down.

In case of 5 threads where 3 tasks are only spawned, 2 unused thread will never be started but there references will remain as it is until shutdown is called in finalize() or all the live threads completes there execution.

Following is the comment from JAVA Docs:

A pool that is no longer referenced in a program AND has no remaining threads will be >shutdown automatically. If you would like to ensure that unreferenced pools are reclaimed >even if users forget to call shutdown(), then you must arrange that unused threads >eventually die, by setting appropriate keep-alive times, using a lower bound of zero core >threads and/or setting allowCoreThreadTimeOut(boolean).

2
votes

In this case, does JVM takes care of the child threads?

The OS manages threads and determines when they are run.

Also I have created a thread pool with 5 threads, but submitted only 3 tasks. Will the remaining 2 threads are terminated when the main thread exits?

No, the threads run until you shut them down.

What actually happens when the executor service is shutdown?

The threads are interrupted and no new tasks will start. However, if you have a task which ignores interrupts it could keep running indefinitely.

When the last non-deamon thread stops the shutdown hook (if any) are triggered.

-1
votes

does JVM takes care of the child threads

JVM only complete its execution after completing all daemon threads. If you are creating your as non daemon then it will wait till all non daemon threads complete.

Will the remaining 2 threads are terminated when the main thread exits

Threads will be created in ondemand mode. So here 3 threads only created not 5.

What actually happens when the executor service is shutdown

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.