Java线程池:空闲线程会发生什么

Rav*_*dra 5 java multithreading threadpool threadpoolexecutor

我正在尝试了解 Java 中的多线程。我编写了以下java程序来测试线程池。

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 );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

主线程创建执行器,它创建 5 个线程,而我只提交了 3 个任务。之后我将关闭执行器。当我运行代码时,主线程先于子线程完成。在这种情况下,JVM 会处理子线程吗?我还创建了一个包含 5 个线程的线程池,但只提交了 3 个任务。当主线程退出时,剩下的2个线程会被终止吗?

当执行程序服务关闭时实际上会发生什么?

abh*_*mal 3

执行器创建的工作线程是内部类,它们具有对执行器本身的引用。(他们需要它才能看到队列、运行状态等!)正在运行的线程不会被垃圾收集,因此池中的每个线程都有该引用,它们将使执行器保持活动状态,直到所有线程都死掉。如果您不手动执行某些操作来停止线程,它们将永远运行,并且您的 JVM 将永远不会关闭。

如果有 5 个线程,其中仅生成 3 个任务,则永远不会启动 2 个未使用的线程,但这些引用将保持原样,直到在 Finalize() 中调用关闭或所有活动线程完成执行。

以下是 JAVA 文档的评论:

程序中不再引用且没有剩余线程的池将自动关闭。如果您想确保未引用的池被回收>即使用户忘记调用 shutdown(),那么您必须通过设置适当的保持活动时间并使用零核心>线程的下限来安排未使用的线程>最终死亡和/或设置allowCoreThreadTimeOut(boolean)。