为什么我们不能在启动线程后调用 setDaemon(true)?


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 ?
}
}

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

根据我的研究,Threadjavadoc总是这样说的。至少可以追溯到Java 1.1.4。

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


为什么?

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

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

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


无论如何,规范说它说什么,所以(最初的)原因是没有意义的…对于所有实际目的。

setDaemon()必须调用线程开始之前。看一看什么是Java中的守护线程?关于守护线程的更多信息