The specification of Thread::setDaemon states:
* <p> This method must be invoked before the thread is started.
but then has:
* @throws IllegalThreadStateException
* if this thread is {@linkplain #isAlive alive}
and is implemented with:
public final void setDaemon(boolean on) {
checkAccess();
if (isAlive()) {
throw new IllegalThreadStateException();
}
daemon = on;
}
The problem is that not isAlive() is not the same as "before the thread has started" as a terminated thread is not alive. Hence the code allows the daemon state of a terminated thread to change - contrary to (at least part of) the specification.
This issue was discovered while investigating an apparent bug in the VM tracking the number of daemon threads - seeJDK-8218483.
Given we can fixJDK-8218483 in the VM, and that this is a long standing "bug" it may not be worth fixing.
* <p> This method must be invoked before the thread is started.
but then has:
* @throws IllegalThreadStateException
* if this thread is {@linkplain #isAlive alive}
and is implemented with:
public final void setDaemon(boolean on) {
checkAccess();
if (isAlive()) {
throw new IllegalThreadStateException();
}
daemon = on;
}
The problem is that not isAlive() is not the same as "before the thread has started" as a terminated thread is not alive. Hence the code allows the daemon state of a terminated thread to change - contrary to (at least part of) the specification.
This issue was discovered while investigating an apparent bug in the VM tracking the number of daemon threads - see
Given we can fix
- relates to
-
JDK-8221893 ApplicationShutdownHook: Thread.isAlive() is not equivalent to not being startable
- Open
-
JDK-8221892 ThreadPoolExecutor: Thread.isAlive() is not equivalent to not being startable
- Resolved
-
JDK-8218483 Crash in "assert(_daemon_threads_count->get_value() > daemon_count) failed: thread count mismatch 5 : 5"
- Resolved