I have a thread that calls a work() method which is a simple while(true)-loop as below;
public void work() throws InterruptedException {
while (true) {
// PART A
if (Thread.currentThread().isInterrupted()) {
System.out.println("....run()::work::PART A::isInterrupted():" + Thread.currentThread().isInterrupted());
Thread.sleep(2000);
}
// Is it possible to make the below code executable at runtime when thread is interrupted?
// PART B
if (Thread.currentThread().isInterrupted()) {
System.out.println("....run()::work::PART B::isInterrupted():" + Thread.currentThread().isInterrupted());
Thread.sleep(2000);
}
}
}
I run this thread instance and interrupt the thread from the main after a period of time with Thread.sleep() method. As I change the delay, I expect to hit the commented part when the thread is interrupted from the main thread but I only see the output below;
....run()::Work::starting
.main()::interrupting thread t
.main()::leaving
....run()::work::PART A::isInterrupted():true
....run()::Work::ERROR::INTERRUPTED
My simple question is this, is it possible to execute the second part (Part B) of the work() method, or if not, why?
The complete demo is as below;
public class GeneralInterrupt implements Runnable {
public void run() {
try {
System.out.println("....run()::Work::starting");
work();
System.out.println("....run()::Work::ended");
} catch (InterruptedException x) {
System.out.println("....run()::Work::ERROR::INTERRUPTED");
return;
}
System.out.println("....run()::Work::leaving normally");
}
public void work() throws InterruptedException {
while (true) {
// PART A
if (Thread.currentThread().isInterrupted()) {
System.out.println("....run()::work::PART A::isInterrupted():" + Thread.currentThread().isInterrupted());
Thread.sleep(2000);
}
// Is it possible to make the below code executable at runtime when thread is interrupted?
// PART B
if (Thread.currentThread().isInterrupted()) {
System.out.println("....run()::work::PART B::isInterrupted():" + Thread.currentThread().isInterrupted());
Thread.sleep(2000);
}
}
}
public static void main(String[] args) {
Thread t = new Thread(new GeneralInterrupt());
t.start();
try {
Thread.sleep(3000);
} catch (InterruptedException x) {
}
System.out.println(".main()::interrupting thread t");
t.interrupt();
System.out.println(".main()::leaving");
}
}
Please also notify that, if the "Thread.sleep(2000)" lines are both removed from the A and B part, then the output is
....run()::work::PART B::isInterrupted():false
....run()::work::PART B::isInterrupted():false
....run()::work::PART B::isInterrupted():false
....run()::work::PART B::isInterrupted():false
....run()::work::PART A::isInterrupted():true
....run()::work::PART A::isInterrupted():true
....run()::work::PART A::isInterrupted():true
....run()::work::PART A::isInterrupted():true
....run()::work::PART A::isInterrupted():true
Can anybody explain why Thread.sleep() method is behaving in such a way inside the work() method.
When you interrupt the thread and it is in the
sleep
method,sleep
will throw anInterruptedException
. You do not handle this exception. It is propagated to yourrun
method and yourwhile
loop exits.You need to surround your
sleep
with a try/catch and catchInterruptedException
. You must also be sure to callThread.currentThread().interrupt()
after catching it, if you wantisInterrupted()
to return true after the exception, since the exception will reset the interrupt flag. Like this: