From the docs:
The Interrupt Status Flag
The interrupt mechanism is implemented using an internal flag known as the interrupt status. Invoking Thread.interrupt sets this flag. When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.
By convention, any method that exits by throwing an InterruptedException clears interrupt status when it does so. However, it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt.
I read these SO posts. But I don't think I have understood this correctly. so I tested this on a sample code below.
I have two threads
running in this. one is main
and other Thread-0
which is labeled t
.
I call t.interrupt()
and I call Thread.currentThread().isInterrupted()
in the run
method.
Where exactly is the flag set?
Does Thread Class
maintains a static list
of all the Threads
that is currently running and by calling Thread.currentThread()
I get the currentThread
Object and check if it is interrupted?
If the Thread class itself has the boolean flag interrupted
, how does it differentiate between two threads; example main
and Thread-0
here. Is the static flag
same to both the Threads
?
what exact sequences of steps are happening, set flag
, where is the look up
and unset flag
etc?
when I uncomment
the block of code
below (which is currently commented out
), the program never stops. I do not understand why?
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class ThreadInterrupt {
public static void main(String[] args) throws InterruptedException {
System.out.println("Starting.");
Thread t = new Thread(new Runnable(){
@Override
public void run() {
Random ran = new Random();
for (int i = 0; i < 1E8; i++) {
/*try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("we have been interrupted");
e.printStackTrace();
}*/
if (Thread.currentThread().isInterrupted()) {
System.out.println("Interrupted!");
break;
}
Math.sin(ran.nextDouble());
}
}
});
t.start();
Thread.sleep(500);
t.interrupt();
t.join();
System.out.println("Finished.");
}
}
when I uncomment the block of code below (which is currently commented out), the program never stops. I do not understand why?
Note the javadoc of Thread#interrupt()
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
So if you uncomment your code, the flag gets lifted and your if
never executes.
Does Thread Class maintains a static list of all the Threads that is currently running and by calling Thread.currentThread()
The Thread.currentThread()
method is declared as (Oracle JDK 7)
public static native Thread currentThread();
In other words, it is natively implemented, probably in C code. We can assume, given the javadoc, that, somewhere, a reference to all threads is stored. The currently executing one is returned.
Similarly, the Thread#isInterrupted()
method calls
private native boolean isInterrupted(boolean ClearInterrupted);
which is also natively implemented. But we can assume it uses some boolean-style flag.