8229516: Thread.isInterrupted() always returns false after thread termination

Reviewed-by: dnsimon, sspitsyn, dcubed, alanb
This commit is contained in:
David Holmes 2019-11-03 18:02:29 -05:00
parent fd077ea9ae
commit 1d50b2761c
30 changed files with 106 additions and 264 deletions

View file

@ -154,6 +154,9 @@ class Thread implements Runnable {
/* 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 @@ class Thread implements Runnable {
*
* <p> 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 @@ class Thread implements Runnable {
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,44 +1012,37 @@ class Thread implements Runnable {
* interrupted again, after the first call had cleared its interrupted
* status and before the second call had examined it).
*
* <p>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 <i>interrupted
* status</i> of the thread is unaffected by this method.
*
* <p>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 @@ class Thread implements Runnable {
private native void suspend0();
private native void resume0();
private native void interrupt0();
private static native void clearInterruptEvent();
private native void setNativeName(String name);
}