Thread.isInterrupted() returns false after thread has been terminated
concurrency, java
Solution
This has been fixed in Java 14.
`Thread.isInterrupted` returns `true` if the thread was interrupted, even if the thread is not alive. See Oracle's release notes and JDK-8229516.
The specification for `java.lang.Thread::interrupt` allows for an implementation to only track the interrupt state for live threads, and previously this is what occurred. As of this release, the interrupt state of a `Thread` is always available, and if you interrupt a thread `t` before it is started, or after it has terminated, the query `t.isInterrupted()` will return true.
The following paragraph has been added to the javadoc of `Thread#interrupt`:
In the JDK Reference Implementation, interruption of a thread that is not alive still records that the interrupt request was made and will report it via `interrupted` and `isInterrupted()`.
So the test in the question runs successfully on:
openjdk version "14.0.2" 2020-07-14
OpenJDK Runtime Environment (build 14.0.2+12)
OpenJDK 64-Bit Server VM (build 14.0.2+12, mixed mode)
The interruption flag is stored as a field in the `Thread` class:
/* Interrupt state of the thread - read/written directly by JVM */
private volatile boolean interrupted;
and `isInterrupted` method simply returns the flag:
public boolean isInterrupted() {
return interrupted;
}
previously it delegated to a `native` `isInterrupted(boolean)` method
Problem
Consider the following JUnit test: ``` @Test public void testSettingInterruptFlag() throws InterruptedException { Thread blockingThread = new Thread(new Runnable() { @Override public synchronized void run() { try { wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }); blockingThread.start(); blockingThread.interrupt(); blockingThread.join(); assertTrue(blockingThread.isInterrupted()); } ``` The test fails even though the interrupted status was set. I've suspected that the line `blockingThread.join();` resets the flag but even when replacing that line with `Thread.sleep(3000);` the test still fails. Is this behaviour documented anywhere?