how to stop a thread with thread interrupt method

coder25 picture coder25 · Aug 8, 2015 · Viewed 7.8k times · Source

I am trying to learn thread interrupt and how to make a thread terminate without calling stop.

public class Test implements Runnable{
        static Thread threadTest=null;
        public static void main(String args[]){
          System.out.println("Hello i am main thread");
          Test thread= new Test();
          threadTest= new Thread(thread);
          threadTest.start();   
}

private static void exitThread() {
    threadTest.interrupt();
}

 @Override
 public void run() {
    boolean run = true;
    while (run) {
        try {
            System.out.println("Sleeping");
            Thread.sleep((long) 10000);
            exitThread();
            System.out.println("Processing");

        } catch (InterruptedException e) {

            run = false;
        }
    }

}


}

Output

Hello i am main thread

Sleeping

Processing

Sleeping

I am unable to understand why Sleeping is printed second time and interrupted exception is thrown second time rather than first time.I have checked posts where volatile keyword is used to stop a thread in java.but i am unable to understand how that will be used in this scenario as thread gets stopped with interrupt.

Answer

Nathan Hughes picture Nathan Hughes · Aug 11, 2015

In order to see the thread being interrupted instead of entering the sleep method a second time, change the while loop test in the run method to check the interrupt flag:

@Override
 public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        try {
            System.out.println("Sleeping");
            Thread.sleep((long) 10000);
            exitThread();
            System.out.println("Processing");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

The thread will sleep, then set its own interrupt flag, then check the flag and terminate. InterruptedException would be thrown by the Thread#sleep method only if the thread was sleeping while the interrupt flag was set.

Your local boolean variable is not needed. If Thread#sleep throws an InterruptedException (which it won't in this example because the thread checks the interrupted flag and leaves the while loop) then the interrupt flag is cleared, restoring it in the catch block allows the while test to see that the thread was interrupted.

In real programs the thread would be interrupted from another thread, there's no reason for a thread to interrupt itself (it can just return instead).