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

使用虚拟线程工厂时Java应用程序立即退出的问题

为什么使用虚拟线程工厂的ScheduledExecutorService会让程序立即退出?

先看你写的代码:

public static void main(String[] args){

  ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(Thread.ofVirtual().factory());

  executor.scheduleWithFixedDelay(() -> System.out.println("A"), 0, 1000, TimeUnit.MILLISECONDS);
  executor.scheduleWithFixedDelay(() -> System.out.println("B"), 0, 1, TimeUnit.MINUTES);

}

运行这段代码时程序会立刻以退出码0结束,但换成Executors.newSingleThreadScheduledExecutor()(不指定虚拟线程工厂),程序就会一直运行,调度任务能正常执行。

核心原因:JVM对线程的退出判定逻辑差异

  • 普通平台线程版本:默认的newSingleThreadScheduledExecutor()会创建一个非守护的平台线程作为调度器的核心工作线程。JVM的退出规则是:必须等所有非守护平台线程都终止,才会停止运行。当main线程执行完代码结束后,这个调度线程还在后台持续运行,所以JVM不会退出,任务能按计划执行。
  • 虚拟线程版本:用Thread.ofVirtual().factory()创建的是虚拟线程作为调度线程。JVM判定是否退出时,只看非守护平台线程的状态,虚拟线程的运行状态不影响JVM退出。main线程是平台线程,它执行完代码后立刻终止,此时JVM中没有其他非守护平台线程在运行,所以直接退出,虚拟调度线程还没来得及执行任务就被终止,程序自然立刻结束。

解决办法

如果想让使用虚拟线程的调度器保持程序运行,只要让main线程不立刻终止即可,比如让它等待调度器的终止信号:

public static void main(String[] args) throws InterruptedException {
  ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(Thread.ofVirtual().factory());

  executor.scheduleWithFixedDelay(() -> System.out.println("A"), 0, 1000, TimeUnit.MILLISECONDS);
  executor.scheduleWithFixedDelay(() -> System.out.println("B"), 0, 1, TimeUnit.MINUTES);

  // 让main线程一直等待,直到调度器被关闭
  executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 00:12:43