繁体   English   中英

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

[英]Java thread pool: What happens to idle threads

我试图理解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 );
        }
    }
}

主线程创建执行器,创建5个线程,我只提交了3个任务。 之后我关闭了遗嘱执行人。 当我运行代码时,主线程在子线程之前完成。 在这种情况下,JVM是否负责子线程? 我还创建了一个包含5个线程的线程池,但只提交了3个任务。 当主线程退出时,剩余的2个线程是否会被终止?

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

来自ExecutorService#shutdown()的文档ExecutorService#shutdown()

启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。

这意味着你提交给执行者的所有工作都将在他们自己的时间内完成,而不会中断或“匆忙”他们,执行人员将正确完成工作线程,但服务也不接受新的工作,也不会立即终止。

比较ExecutorService#shutdownNow() ,它将尝试尽快终止。

执行程序创建的Worker线程是内部类,它们具有对执行程序本身的引用。 (他们需要它能够看到队列,runstate等等!)运行线程不是垃圾收集的,所以当池中的每个线程都有该引用时,它们将使执行器保持活动状态直到所有线程都死亡。 如果您不手动执行某些操作来停止线程,它们将永远保持运行,您的JVM将永远不会关闭。

如果5个线程只生成3个任务,则永远不会启动2个未使用的线程但是引用将保持不变,直到在finalize()中调用shutdown或所有活动线程完成执行。

以下是JAVA Docs的评论:

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

在这种情况下,JVM是否负责子线程?

操作系统管理线程并确定它们何时运行。

我还创建了一个包含5个线程的线程池,但只提交了3个任务。 当主线程退出时,剩余的2个线程是否会被终止?

不,线程一直运行,直到你关闭它们。

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

线程被中断,不会启动任何新任务。 但是,如果您有一个忽略中断的任务,它可以无限期地继续运行。

当最后一个非deamon线程停止时,将触发关闭钩子(如果有)。

JVM是否负责子线程

JVM仅在完成所有守护程序线程后完成其执行。 如果您正在创建非守护进程,那么它将等待所有非守护进程线程完成。

当主线程退出时,剩余的2个线程是否会终止

线程将在按需模式下创建。 所以这里3个线程只创建了5个。

执行程序服务关闭时实际发生的情况

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.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM