【问题标题】:why we can't call setDaemon(true) after starting thread?为什么我们不能在启动线程后调用 setDaemon(true)?
【发布时间】:2021-11-30 18:54:57
【问题描述】:
public class MyThread extends Thread {

    public void run() {
        System.out.println("Thread is running");
    }

    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        t1.start(); 
        t1.setDaemon(true); // throw IllegalThreadStateException why ?
    }
}

【问题讨论】:

  • 基本上,因为 javadoc 是这么说的。为什么?好吧,我想如果线程在启动后可以在守护程序和非守护程序之间切换,它可能会在一些(可能是假设的)平台上出现实现困难。无论如何,规范说明了它所说的,所以真正的原因是没有实际意义的......出于所有实际目的。
  • 请注意,从我可以在网上找到的最早版本开始,javadocs 就已经说过了; Java 1.1.4。

标签: java multithreading daemon


【解决方案1】:

Threadjavadocs 明确声明必须在线程启动之前调用setDaemon1

根据我的研究,Thread javadocs 一直这么说。至少可以追溯到 Java 1.1.4。

1 - 但有趣的是,Loom 的 draft javadocs 声明在线程终止后调用 setDaemon 的行为是未指定


为什么?

一个可能的原因是,如果一个线程的守护进程状态可以在它处于活动状态时发生变化,那么就很难确定 JVM 何时应该退出。考虑当最后一个非守护线程同时终止而守护线程将自身设置为非守护线程时会发生什么。 JVM 是否退出?

如果一个正在运行的线程的守护进程状态可以改变,那么显然存在“竞争”的可能性,并且不清楚应用程序将如何缓解它们......除非 Java SE 库提供了一些额外的(可能是复杂的)基础设施来处理有了这个。

如果我是Thread API 的设计者,我会问为什么正在运行的线程需要 在守护程序和非守护程序状态之间切换(或被切换)?我想不出一个现实的用例;即实现有用的行为,但不能以其他方式实现。


无论如何,规范说明了它所说的内容,因此(原始)原因是没有实际意义的......出于所有实际目的。

【讨论】:

    【解决方案2】:

    setDaemon() 必须在线程启动之前调用。看一下 What is a daemon thread in Java? 更多关于守护线程的信息。

    【讨论】:

    • 这个答案没有解释为什么之前应该调用它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多