When we call the Wait () method of a Java object or the sleep() method of a thread, we catch and handle InterruptedException. If we mishandle InterruptedException, unexpected consequences can occur!

This article is based on InterruptedException. It is InterruptedException that causes InterruptedException.

preface

When calling the Wait () method of a Java object or the sleep() method of a thread, you need to catch and handle the Interrupted Exception. If we do not handle the Interrupted Exception properly, we will have unexpected consequences!

Application case

For example, in the following code, the Interrupted Task class implements the Runnable interface by getting a handle to the current thread in the run() method and checking whether the current thread has been Interrupted through the isInterrupted() method in the while(true) loop. If the current Thread is Interrupted it exits the while(true) loop with a line of Thread.sleep(100) code that catches the Interrupted Exception. The entire code is shown below.

package io.binghe.concurrent.lab08; /** * @author binghe * @version 1.0.0 * @description thread test interrupt */ public class Interrupted Task implements Runnable{ @Override public void run() { Thread currentThread = Thread.currentThread(); while (true){ if(currentThread.isInterrupted()){ break; } try { Thread.sleep(100); } catch (Interrupted Exception e) { e.printStack Trace(); }}}}Copy the code

The intent of the above code is to check if the thread has been interrupted with the isInterrupted() method and exit the while loop if it has. Other threads by calling thread of execution of interrupt () method to interrupt execution threads, this will set the interrupt flag bit of thread of execution, so that the currentThread. IsInterrupted () returns true, so you can exit the while loop.

That doesn’t seem to be a problem! But is it really true? We create a Interrupted Test class for testing, with the code shown below.

package io.binghe.concurrent.lab08; /** * @author binghe * @version 1.0.0 * @description Test thread interrupt */ public class InterruptedTest {public static void main(String[] args){ InterruptedTask interruptedTask = new InterruptedTask(); Thread interruptedThread = new Thread(interruptedTask); interruptedThread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } interruptedThread.interrupt(); }}Copy the code

We run the main method, as shown below.

This is not what we expected! Not the same! Not the same! Why is that?

Problem analysis

The above code explicitly calls the thread’s interrupt() method to interrupt the thread, but it does nothing. The reason for this is that the thread’s run() method blocks most of the time on the sleep(100). If other threads interrupt the thread by calling interrupt(), they will raise a Interrupted Exception. If this Exception isInterrupted by running (), the JVM clears the Thread’s interrupt flag. If this Exception isInterrupted by running (), the JVM returns false. I would not exit the current while loop.

Now that the problem analysis is cleared, how do I interrupt the thread and exit the program?

Problem solving

The correct way to handle this is to reset the interrupt flag bit after catching the exception in the while(true) loop in the run() method of the Interrupted Task class, so the correct code for the Interrupted Task class is shown below.

package io.binghe.concurrent.lab08; /** * @author binghe * @version 1.0.0 * @description public class InterruptedTask implements Runnable{ @Override public void run() { Thread currentThread = Thread.currentThread(); while (true){ if(currentThread.isInterrupted()){ break; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); currentThread.interrupt(); }}}}Copy the code

As you can see, we have added a line of code to the catch block that catches the Interrupted Exception.

currentThread.interrupt();
Copy the code

This allows us to catch a Interrupted Exception and reset the interrupt flag bit of the thread, thus interrupting the currently executing thread.

We run the main method of the Interrupted Test class again, as shown below.

conclusion

If interrupt() throws a interrupt Exception when calling the interrupt() method of the executing thread, the Exception will be Interrupted by a interrupt() Exception. The JVM also clears the interrupt flag of the executing thread and returns false when isInterrupted() is invoked. The correct way to handle this is to catch the Interrupted Exception in the run() method of the executing thread and reset the interrupt flag bit (in the catch block that catches the Interrupted Exception, Reinvoke the interrupt() method of the current thread.

Click to follow, the first time to learn about Huawei cloud fresh technology ~