-1

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.");
    }

}
Community
  • 1
  • 1
brain storm
  • 30,124
  • 69
  • 225
  • 393
  • 1
    this link has good information : http://10kloc.wordpress.com/2013/03/03/java-multithreading-steeplechase-stopping-threads/ – eagertoLearn Mar 12 '14 at 03:53

2 Answers2

4

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.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • whether the `if` statement is executed or not, the program should stop correct? – brain storm Feb 28 '14 at 19:38
  • @user1988876 When the `for` loop eventually exits. – Sotirios Delimanolis Feb 28 '14 at 19:39
  • when I interrupt during the `sleep` mode, it is simply ignored? atleast here it is caught in the `catch` block? but what if I want to stop the thread.? – brain storm Feb 28 '14 at 19:48
  • @user1988876 It's not exactly ignored. The `interrupt()` method raises the flag. The fact that the interrupted thread is in `sleep()` will cause the JVM to drop the flag and throw an `InterruptedException` in that thread's execution. You have to understand that thread interruption is something the developer has to implement. It's not done automatically. [Here's the tutorial](http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html) if you are interested. – Sotirios Delimanolis Feb 28 '14 at 19:51
  • Thanks for the tutorial link, it is the same one I linked above in my question. but I do not see an explanation as how to stop a thread when it in sleeping mode. I just want to terminate a thread if it is interrupted...and +1 for clarifications – brain storm Feb 28 '14 at 19:56
  • 1
    @user1988876 In your commented implementation, you `break;` and the `run()` method terminates. In your uncommented implementation, the `InterruptedException` is caught, you can `return;` right away if you want so that the `Thread` terminates. It depends how you (want to) implement it. There are other situations where an `InterruptedException` can be thrown (see the javadoc quoted above). Keep those in mind. Similarly you can keep checking `isInterrupted()` and `return;` if you need/want to. – Sotirios Delimanolis Feb 28 '14 at 19:58
  • `return` is the keyword I suppose, by `return`, I come out of `run()` method and thats the end of current thread? – brain storm Feb 28 '14 at 20:02
1

Where exactly is the flag set?

The JVM Thread object keeps track of the flag.

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?

The Thread Class doesn't do it but the JVM does. Thread.currentThread() is a static method which returns the Thread object that is associated with the calling thread.

If the Thread class itself has the boolean flag interrupted, how does it differentiate between two threads; example main and Thread-0 here

It is an instance field not a static field. It is per Thread instance.

when I uncomment the block of code below (which is currently commented out), the program never stops. I do not understand why?

Because when you interrupt the thread, Thread.sleep(...) throws InterruptedException which clears the interrupt flag for the thread. You always should re-interrupt the thread once you catch InterruptedException.

try {
     Thread.sleep(100);
} catch (InterruptedException e) {
     // _always_ reinterrupt the thread when you catch InterruptedException
     Thread.currentThread().interrupt();
     System.out.println("we have been interrupted");
     e.printStackTrace();
}
Gray
  • 115,027
  • 24
  • 293
  • 354
  • so can I assume that JVM will have a list of all the running threads, with its name, flag status and so on. but then when a thread instance asks if it is interrupted, how will the JVM knows which thread is making the inquiry? – brain storm Feb 28 '14 at 19:50
  • The magic is in `Thread.currentThread()` which returns the thread that the caller is running in. That's magic from the JVM. It just works @user1988876. Once you have the current thread then you can call `thread.isInterrupted()`. – Gray Feb 28 '14 at 19:56