2

Please first see this snippet:

public static void main(String[] args) throws InterruptedException {
    Thread anotherThread = new Thread(() -> {
        Integer countB = 0;
        while (true) {
            try {
                System.out.println("B count: " + ++countB);
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    anotherThread.start();

    Integer countA = 0;
    while (true) {
        System.out.println("A count: " + ++countA);
        Thread.sleep(1000);
    }
}

This works as expected. I see countA to be approximately 2x of countB.

Now I add one line to the outer while loop:

public static void main(String[] args) throws InterruptedException {
    Thread anotherThread = new Thread(() -> {
        Integer countB = 0;
        while (true) {
            try {
                System.out.println("B count: " + ++countB);
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    anotherThread.start();

    Integer countA = 0;
    while (true) {
        anotherThread.interrupt();
        System.out.println("A count: " + ++countA);
        Thread.sleep(1000);
    }
}

Main thread interrupts anotherThread. After I do this, countA is no longer 2x countB. They always differ by one now.

Why so? How does sleep/interrupt work?

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
Boyang
  • 2,520
  • 5
  • 31
  • 49

4 Answers4

3

Basically calling interrupt will wake up the thread from it's sleep call. Generally you would interrupt a thread because you want it to gracefully end... but in this case it just gets woken up, and then keeps on going within it's infinite loop.

Check out the docs for more information: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

Buddy
  • 10,874
  • 5
  • 41
  • 58
0

This is an addition to Buddy's answer, which is correct.

In first case you have

B    A
.    .
.    A
.    .
B    A
.    .
.    A
.    .
B    A

but with interrupt it changed to:

B    A (interrupts B, B continues in loop)
B    .
.    A (interrupts B again)
B    .
.    A
B    .
.    A
B    .
.    A

causing B not to wait 2 seconds...

Community
  • 1
  • 1
Betlista
  • 10,327
  • 13
  • 69
  • 110
  • Thanks. Now I understand. And to be sure, I came up with the question from Oracle Java tutorial – Boyang Dec 02 '15 at 07:42
0

If you interrupt anotherThread it will wakeup from its sleep. In other words it doesn't sleep 2sec but only 1sec like your Main-Thread (countA).

What interrupt does: It wakes a Thread that is in state sleep. The method sleep(int) will throw an InterrruptedException when interrupt() is called to indicate that the time not elapsed.

Chriss
  • 5,157
  • 7
  • 41
  • 75
0

Interruption requires the thread being interrupted to cooperate, it has to look for signs that it has been interrupted and handle them. If you change anotherThread to this:

Thread anotherThread = new Thread(() -> {
    Integer countB = 0;
    while (!Thread.currentThread().isInterrupted()) {
        try {
            System.out.println("B count: " + ++countB);
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }
});

then interrupting the thread will cause it to finish.

Calling interrupt sets the interruption flag, when the thread is sleeping and detects the flag is set then the sleep method throws an InterruptedException , also clearing the interrupt flag on the thread. Calling interrupt on the thread in the catch block is needed in order to restore the flag value. Then having the while loop test check the interrupt flag gives the thread the opportunity to quit.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276