【问题标题】:Do Java Executors run in a daemon thread?Java Executors 是否在守护线程中运行?
【发布时间】:2018-09-13 17:31:22
【问题描述】:

我有一个简短的 java 程序,它创建了一个单线程调度执行器,我调度了一个任务。

ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();

scheduledExecutorService.schedule(cloudWatchReporter, accumulateForMillis, TimeUnit.MILLISECONDS);

在预定时间到来之前,我的主线程结束了,JVM退出了。我曾期望它会等待计时器完成并在关闭之前执行计划任务。这不是发生的事情。如果我在主线程结束之前添加了足够的睡眠,那么我的任务将在 JVM 关闭之前执行。

Executor 是否有一个管理计时器的主线程?还是以其他方式实现的定时器效果?如果由某个主线程管理,它是守护线程还是非守护线程?

【问题讨论】:

  • 参见defaultThreadFactory() 的javadoc:返回用于创建新线程的默认线程工厂。该工厂在同一个 ThreadGroup 中创建 Executor 使用的所有新线程。 [...] 每个新线程都被创建为非守护线程,优先级设置为 Thread.NORM_PRIORITY 和线程组中允许的最大优先级中的较小者。 [...]
  • @SotiriosDelimanolis 我没有问池中的线程是守护进程还是非守护进程。我询问是否存在为池创建线程的线程,以及该线程是守护进程还是非守护进程。
  • JDK 实现中的所有线程ScheduledExecutorService 从主“队列”中拉取任务。没有“管理”线程。线程是根据需要从调用任何schedule 方法的线程创建和启动的(在您的情况下最多为 1 个)。
  • 计时器如何运行?
  • 每个线程循环尝试从共享优先级队列中获取数据,或多或少地休眠最顶层元素(如果存在)的持续时间。

标签: java multithreading executorservice


【解决方案1】:

这个简单的完整示例与您在问题中声称的内容相矛盾:

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

class Test {

    public static void main(String[] args) {
        ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService.schedule(() -> System.out.println("hello"), 10, TimeUnit.SECONDS);
    }
}

运行它,你会看到不仅消息在 10 秒后打印出来,而且程序也没有退出。所以你的主线程并没有简单地结束。你可能会打电话给System.exit()

【讨论】:

  • 我运行了您提供的代码。它像你说的那样工作。但是当作为 JUnit 测试的一部分执行时,我无法让 main 方法中的这两行以相同的方式运行。测试在打印文本“hello”之前退出。 JUnit 测试代码的运行方式是否与从 main 方法执行不同?我之前没有提到它,但我最初对 schedule 方法的调用是在 JUnit 测试中发生的。
  • JUnit 执行器很可能会在所有测试执行完毕后立即调用 System.exit()。如果您希望调度的作业运行,您需要阻止测试足够长的时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
相关资源
最近更新 更多