You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Executor线程在主类结束后持续运行,而普通线程不会?

为什么两段代码的程序终止行为不同?

这个问题的核心在于线程是否被实际启动,以及线程池工作线程的存活特性,咱们一步步拆解清楚:

第一段代码:线程池的用户线程阻止JVM退出

先看你的第一段代码:

Executor executor = Executors.newFixedThreadPool(1); 
executor.execute(new Runnable() { 
    public void run() { 
        try { 
            System.out.println("sleep"); 
            Thread.sleep(5000); 
        } catch (InterruptedException e) { 
            System.out.println("Interrupted, so exiting."); 
        } 
    } 
});

这里你做了两个关键操作:

  • 通过Executors.newFixedThreadPool(1)创建的固定大小线程池,它的核心线程默认不会自动销毁——即使任务执行完毕,工作线程也会留在池中等待新任务,不会自行结束。
  • 调用execute()提交任务后,线程池会启动一个用户线程来执行你的Runnable逻辑。

JVM的终止规则是:只有当所有用户线程都执行完毕后,JVM才会退出。而线程池的这个工作线程在睡5秒完成任务后,依然处于活跃等待状态,属于未结束的用户线程,所以JVM会一直等待,程序自然无法终止。

如果想让这段代码的程序正常终止,你需要手动关闭线程池,比如在execute()之后添加((ExecutorService)executor).shutdown(),这样线程池会在任务执行完毕后销毁工作线程,JVM就能正常退出了。

第二段代码:线程根本没被启动

再看你的第二段代码:

Thread t = new Thread(new Runnable() { 
    public void run() { 
        try { 
            Thread.sleep(5000); 
        } catch (InterruptedException e) { 
            e.printStackTrace(); 
        } 
    } 
});

这里你只是创建了一个Thread对象,但从来没有调用t.start()方法启动这个线程!也就是说,Runnable里的休眠逻辑根本没有被执行,程序中只有主线程在运行。当主线程执行完这段代码后,没有其他活跃的用户线程,JVM直接终止,所以程序看起来正常结束了。

如果你给这段代码加上t.start(),会发现程序也不会终止——因为启动后的Thread默认是用户线程,它会执行5秒休眠,期间JVM会等待它执行完毕才会退出。

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:58:32