Reputation: 2566
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?
Upvotes: 2
Views: 1589
Reputation: 96444
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.
Upvotes: 0
Reputation: 5639
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.
Upvotes: 0
Reputation: 10547
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...
Upvotes: 0
Reputation: 11038
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
Upvotes: 3