Search code examples
javamultithreadinginterrupt

Single Thread.interrupt() interrupts more than once


I created MyTask which has 3 things to do inside run(). I try to interrupt() the thread which holds MyTask instance. Unfortunately once it is interrupted, it ends and only string First task is printed on the console.

public class MyTask implements Runnable {
    private volatile Thread thread;

    @Override
    public void run() {
        while (!thread.isInterrupted()) {
            System.out.println("First task");
        }
        while (!thread.isInterrupted()) {
            System.out.println("Second task");
        }
        while (!thread.isInterrupted()) {
            System.out.println("Third task");
        }
    }

    public Thread start(){
        thread = new Thread(this);
        thread.start();
        return thread;
    }


    public static void main(String[] args) throws InterruptedException {
        Thread t = new MyTask().start();
        Thread.sleep(1000);
        t.interrupt();
        Thread.sleep(1000);
        t.interrupt();
        Thread.sleep(1000);
        t.interrupt();
    }

}

If I add Thread.sleep(10) in the run() it starts to work correctly and it prints First task, Second task and finally Third task on the console.

The question is: Whydoes Thread.interrupts() work correctly only if I add sleep()?

public class MyTask implements Runnable {
    private volatile Thread thread;

    @Override
    public void run() {
        while (!thread.isInterrupted()) {
            System.out.println("First task");
        }
        try {
            Thread.sleep(10);
        } catch (Exception e) {
        }
        while (!thread.isInterrupted()) {
            System.out.println("Second task");
        }
        try {
            Thread.sleep(10);
        } catch (Exception e) {
        }
        while (!thread.isInterrupted()) {
            System.out.println("Third task");
        }
    }

    public Thread start(){
        thread = new Thread(this);
        thread.start();
        return thread;
    }


    public static void main(String[] args) throws InterruptedException {
        Thread t = new MyTask().start();
        Thread.sleep(1000);
        t.interrupt();
        Thread.sleep(1000);
        t.interrupt();
        Thread.sleep(1000);
        t.interrupt();
    }

}

Solution

  • To quote from Interrupts:

    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.

    Meaning: Change your code from thread.isInterrupted() to Thread.interrupted() and try again.

    The sleep() in between your loops will clear that flag as well by throwing InterruptedException immediately (as the current Thread has been interrupted)