As reported by Thomas Stuefe in:
http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2019-April/033512.html
ApplicationShutdownHook.java:
static synchronized void add(Thread hook) {
if(hooks == null)
throw new IllegalStateException("Shutdown in progress");
if (hook.isAlive())
throw new IllegalArgumentException("Hook already running");
if (hooks.containsKey(hook))
throw new IllegalArgumentException("Hook previously registered");
hooks.put(hook, hook);
}
would register a terminated thread as shutdown hook.
---
When start that hook we would get an IllegalThreadStateException that would terminate the hook starting and joining logic:
static void runHooks() {
Collection<Thread> threads;
synchronized(ApplicationShutdownHooks.class) {
threads = hooks.keySet();
hooks = null;
}
for (Thread hook : threads) {
hook.start(); <= // BOOM!
}
for (Thread hook : threads) {
while (true) {
try {
hook.join();
break;
} catch (InterruptedException ignored) {
}
}
}
}
We need to check for getState() == Thread.State.NEW
http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2019-April/033512.html
ApplicationShutdownHook.java:
static synchronized void add(Thread hook) {
if(hooks == null)
throw new IllegalStateException("Shutdown in progress");
if (hook.isAlive())
throw new IllegalArgumentException("Hook already running");
if (hooks.containsKey(hook))
throw new IllegalArgumentException("Hook previously registered");
hooks.put(hook, hook);
}
would register a terminated thread as shutdown hook.
---
When start that hook we would get an IllegalThreadStateException that would terminate the hook starting and joining logic:
static void runHooks() {
Collection<Thread> threads;
synchronized(ApplicationShutdownHooks.class) {
threads = hooks.keySet();
hooks = null;
}
for (Thread hook : threads) {
hook.start(); <= // BOOM!
}
for (Thread hook : threads) {
while (true) {
try {
hook.join();
break;
} catch (InterruptedException ignored) {
}
}
}
}
We need to check for getState() == Thread.State.NEW
- relates to
-
JDK-8221657 java.lang.Thread::setDaemon modifies the state of terminated threads
-
- Open
-
-
JDK-8221892 ThreadPoolExecutor: Thread.isAlive() is not equivalent to not being startable
-
- Resolved
-