Java interrupt thread (interrupt)
@author: Jingdai
@date:2020.10.06
concept
When
A
a thread wantsB
the thread terminates, how should we do it? In previous versions of Java, you can usestop
the method to make a thread to terminate, but this method has been abandoned, do not use it.You can now
A
calling thread inB
the threadinterrupt()
method to theB
thread know you want to make your own thread to terminate, but depends on whether or not to terminateB
a thread yourself,B
can ignore the termination request. (Of course it's better not to do this) Let's take a look at the details.
Related function introduction
void interrupt()
Interrupt this thread.
boolean isInterrupted()
Check if this thread is interrupted.
static boolean interrupted()
Check whether the current thread is interrupted. This method will also clear the interruption status of the thread after it is called.
Example explanation
boolean isInterrupted()
Method andstatic boolean interrupted()
method differenceFirst, the following code Test
boolean isInterrupted()
Method.public static void main(String[] args) { Thread.currentThread().interrupt(); System.out.println(Thread.currentThread().isInterrupted()); // true System.out.println(Thread.currentThread().isInterrupted()); // true }
You will find that the output is both times
true
.Then test
static boolean interrupted()
methods.public static void main(String[] args) { Thread.currentThread().interrupt(); System.out.println(Thread.interrupted()); // true System.out.println(Thread.interrupted()); // false }
The test found that the first output is true, and the second output is false, indicating that this method will clear the interruption status of the thread after it is called.
Interrupt and ignore
Here we get the main thread interrupts thread
aThread
, butaThread
the thread ignore, to see what happens. code show as below:public static void main(String[] args){ // create and start aThread Runnable r = () -> { while (true) { System.out.println("I'm alive"); } }; Thread aThread = new Thread(r); aThread.start(); // interrupt aThread aThread.interrupt(); }
Tests found
aThread
no effect of running threads, or has been outputI'm alive
.General usage
Since there will be no effect if the interrupt is not processed, how should you respond to the interrupt? It should always be judged whether the thread is interrupted in the thread. If the thread is interrupted, the next work should be selected according to the requirements of the current task, and the necessary resources should be shut down before ending the thread. Look at the code below.
public static void main(String[] args){ // create and start aThread Runnable r = () -> { try { while (!Thread.currentThread().isInterrupted()) { //do work System.out.println("I'm alive"); } System.out.println("I ll die"); } finally { // close some resources } }; Thread aThread = new Thread(r); aThread.start(); try { Thread.currentThread().sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } // interrupt aThread aThread.interrupt(); }
When the thread has not been interrupted, has been implementing its mandate, when interrupted, it will be out of the loop and
finally
closes the corresponding resources and do some clean-up and operation.When the thread is blocked
The above situation can be run in the thread is not blocked, but when the thread is blocked, the thread is unable to check the thread's interrupt status, so the introduction of
InterruptedException
an exception to help break blocked. There are some differences between different blocking, as follows.
Thread
sleep()
method orjoin()
when the method blocksThe following code:
public static void main(String[] args) { // create and start aThread Runnable r = () -> { try { Thread.currentThread().sleep(5000); } catch (InterruptedException e) { System.out.println("die"); e.printStackTrace(); } finally { // close some resources } }; Thread aThread = new Thread(r); aThread.start(); try { Thread.currentThread().sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } // interrupt aThread aThread.interrupt(); }
Calls on these threads
interrupt()
when the method,sleep()/join()
the method will be interrupted no longer executed, it clears the interrupt status and directly jump into thecatch
block in execution, so if you call in a loopsleep()
method is not going to detect the interrupt status, as it will directly jump thecatch
blocks being performed, it should be directly capturedInterruptedException
exception.Thread is
wait()
when the method blocksThread is
wait()
when blocking method, callinginterrupt()
effect and thread method issleep()
a method orjoin()
blocking the effect of essentially the same way, it also clears the interrupt status and jumped into thecatch
block to execute. But there is a little bit different, that is, theinterrupt()
calling thread will go to get calledwait()
lock object method, after obtaining the finished object will lock and thrown into thecatch
block to execute, if not get a lock, then you can not throw an abnormality can not entercatch
the block. The following code, firstaThread
obtain the lock andwait
(notewait()
method will release the lock), thenbThead
get the lock, butb
never release the lock, ataThread
wait
the time, the main thread callsinterrupt()
to interruptaThread
, but becauseaThread
never get a lock, so it will not throw an exception, It does not enter into thecatch
block operation. code show as below.public static void main(String[] args) { Runnable r = () -> { try { synchronized (o) { System.out.println("aThread get lock"); o.wait(10000); } } catch (InterruptedException e) { e.printStackTrace(); // can't come here } }; Thread aThread = new Thread(r); aThread.start(); Runnable r2 = () -> { try { Thread.currentThread().sleep(250); synchronized (o) { System.out.println("bThread get lock"); while (true) { } } } catch (InterruptedException e) { e.printStackTrace(); } }; Thread bThread = new Thread(r2); bThread.start(); try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // interrupt aThread aThread.interrupt(); }
Other blocking
There are other blocking situations in the API. If the thread is
InterruptibleChannel
IO operation blocked, then the pipeline will be shut down, thread's interrupt status will be set, and it will throw anClosedByInterruptException
exception.If the thread is
Selector
blocked, then the thread's interrupt status will be set, and returns immediately from the selection operation may return a nonzero value, asselector
thewakeup
method is called the same.I haven't used either of these two kinds of blocking (too unpleasant), so I didn't write code to test, and I would test when I encountered it.
In addition to the above cases, the interrupt status of the thread will be set in other cases.
reference
- Java Core Technology Volume 1 Chapter 12
- Java8 API