--- old/src/java.base/share/classes/java/lang/Thread.java 2019-10-29 02:51:41.685775665 -0400 +++ new/src/java.base/share/classes/java/lang/Thread.java 2019-10-29 02:51:40.471761364 -0400 @@ -154,6 +154,9 @@ /* Whether or not the thread is a daemon thread. */ private boolean daemon = false; + /* Interrupt state of the thread - read/written directly by JVM */ + private volatile boolean interrupted; + /* Fields reserved for exclusive use by the JVM */ private boolean stillborn = false; private long eetop; @@ -971,10 +974,14 @@ * *

Interrupting a thread that is not alive need not have any effect. * + * @implNote 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 {@link #interrupted} and {@link #isInterrupted()}. + * * @throws SecurityException * if the current thread cannot modify this thread * - * @revised 6.0 + * @revised 6.0, 14 * @spec JSR-51 */ public void interrupt() { @@ -985,14 +992,15 @@ synchronized (blockerLock) { Interruptible b = blocker; if (b != null) { - interrupt0(); // set interrupt status + interrupted = true; + interrupt0(); // inform VM of interrupt b.interrupt(this); return; } } } - - // set interrupt status + interrupted = true; + // inform VM of interrupt interrupt0(); } @@ -1004,45 +1012,38 @@ * interrupted again, after the first call had cleared its interrupted * status and before the second call had examined it). * - *

A thread interruption ignored because a thread was not alive - * at the time of the interrupt will be reflected by this method - * returning false. - * * @return {@code true} if the current thread has been interrupted; * {@code false} otherwise. * @see #isInterrupted() - * @revised 6.0 + * @revised 6.0, 14 */ public static boolean interrupted() { - return currentThread().isInterrupted(true); + Thread t = currentThread(); + boolean interrupted = t.interrupted; + // We may have been interrupted the moment after we read the field, + // so only clear the field if we saw that it was set and will return + // true; otherwise we could lose an interrupt. + if (interrupted) { + t.interrupted = false; + clearInterruptEvent(); + } + return interrupted; } /** * Tests whether this thread has been interrupted. The interrupted * status of the thread is unaffected by this method. * - *

A thread interruption ignored because a thread was not alive - * at the time of the interrupt will be reflected by this method - * returning false. - * * @return {@code true} if this thread has been interrupted; * {@code false} otherwise. * @see #interrupted() - * @revised 6.0 + * @revised 6.0, 14 */ public boolean isInterrupted() { - return isInterrupted(false); + return interrupted; } /** - * Tests if some Thread has been interrupted. The interrupted state - * is reset or not based on the value of ClearInterrupted that is - * passed. - */ - @HotSpotIntrinsicCandidate - private native boolean isInterrupted(boolean ClearInterrupted); - - /** * Tests if this thread is alive. A thread is alive if it has * been started and has not yet died. * @@ -2080,5 +2081,6 @@ private native void suspend0(); private native void resume0(); private native void interrupt0(); + private static native void clearInterruptEvent(); private native void setNativeName(String name); }