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

Java线程池:空闲线程会发生什么情况,java,multithreading,threadpool,threadpoolexecutor,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++ ) {

我试图理解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 );
        }
    }
}
公共类线程池测试
{
公共静态void main(字符串[]args)
{
ExecutorService ExecutorService=Executors.newFixedThreadPool(5);
对于(int i=0;i<3;i++)
{
executorService.submit(新任务(i+1));
}
executorService.shutdown();
}
公共静态类任务实现可运行
{
私有int taskId;
公共任务(int-id)
{
taskId=id;
}
@凌驾
公开募捐{
System.out.println(“执行任务”+taskId+”,由“+Thread.currentThread().getName()执行);
尝试
{
睡眠(3000);
}
捕获(中断异常中断)
{
System.out.println(Thread.currentThread().getName()+“被中断”);
}
System.out.println(“已完成执行任务”+taskId);
}
}
}
主线程创建executor,它创建了5个线程,我只提交了3个任务。之后,我将关闭遗嘱执行人。当我运行代码时,主线程在子线程之前完成。在这种情况下,JVM负责子线程吗? 我还创建了一个包含5个线程的线程池,但只提交了3个任务。当主线程退出时,剩余的2个线程是否会终止


当executor服务关闭时,实际会发生什么情况?

来自
executor服务#shutdown()
的文档:

启动有序关机,在该关机过程中,以前提交的任务将被删除 已执行,但不会接受新任务

这意味着您提交给执行者的所有作业都将在自己的时间内完成,而不会中断或“催促”它们,执行者将正确完成工作线程,但服务既不会接受新作业,也不会立即终止


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

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

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

以下是JAVA文档的评论:

程序中不再引用且没有剩余线程的池将自动>关闭。如果要确保回收未引用的池>,即使用户忘记调用shutdown(),则必须通过设置适当的保持活动时间,使用zero core>threads下限和/或设置allowCoreThreadTimeOut(布尔值),安排未使用的线程>最终消亡

在这种情况下,JVM负责子线程吗

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

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

不,线程将一直运行,直到您关闭它们

当executor服务关闭时,实际会发生什么

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


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

JVM是否处理子线程

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

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

线程将在ondemand模式下创建。所以这里只创建了3个线程,而不是5个

当executor服务关闭时实际会发生什么

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.

但是空闲线程运行什么呢?如果我使用了一个线程,然后很长时间没有给出任务,那么一旦初始任务完成,该线程将运行什么?它只会忙着循环并耗尽cpu吗?