This blog will introduce the interrupt()
method and termination of threads. The contents include:
interrupt()
introduction- The way to terminate the thread
- Terminate threads in the
blocked state
- Terminate threads in the
running state
- Terminate threads in the
- Example of thread termination
- The difference between
interrupted()
andisInterrupted()
interrupt() introduction
Regarding interrupt()
, look at the java jdk11
documentation(https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.html#interrupt()):
Interrupts this thread.
Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown.
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an InterruptibleChannel then the channel will be closed, the thread’s interrupt status will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread’s interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector’s wakeup method were invoked.
If none of the previous conditions hold then this thread’s interrupt status will be set.
Interrupting a thread that is not alive need not have any effect.
The way to terminate the thread
The stop()
and suspend()
methods in Thread
have been suggested not to be used due to inherent insecurity!
Then, let’s first discuss the termination of threads in the blocked state
and running state
, and then summarize a general method.
Terminate threads in the blocked state
Normally, we terminate threads in blocked state
by interrupting.
When the thread is blocked due to calling sleep()
, wait()
, join()
etc, if the interrupt()
method of the thread is called at this time, the thread’s interrupt flag is set to true
. Due to the blocked state
, the interrupt flag will be cleared and an InterruptedException
exception will be generated. Put the InterruptedException
at the appropriate place can terminate the thread.
1 |
|
Continuously execute tasks in while(true)
. When the thread is blocked, the interrupt()
of the calling thread generates an InterruptedException
exception. The exception is captured outside of while(true)
, so that the while(true)
loop is exited!
Note: the capture of InterruptedException
is generally placed outside the body of the while(true)
loop, so that when the exception occurs, the while(true)
loop is exited. Otherwise, the InterruptedException
is within the while(true)
loop, and additional exit processing needs to be added.
1 |
|
Terminate threads in the running state
Usually, we terminate the thread in running state
by flagging, including interrupt flag
and additional flag
.
Use interrupt flag
1 |
|
isInterrupted()
will determine whether the thread’s interrupt flag
is true
. When the thread is running and we need to terminate it, we can call the thread’s interrupt()
method to make the thread’s interrupt flag
as true
. Then isInterrupted()
will return true
. At this point, the while loop will exit.
Note: interrupt()
does not terminate the thread in the running state
! It will set the thread’s interrupt flag
to true
.
Use additional flag
1 | private volatile boolean flag = true; |
There is a flag boolean in the thread, and its default value is true
. We provide stopTask()
to set the flag. When we need to terminate the thread, call the thread’s stopTask()
method to let the thread exit the while loop.
Note: The flag is set as volatile
to ensure the visibility of flag. That is, after other threads modify the flag through stopTask()
, the current thread can see the value of the modified flag.
The more general form of termination thread is as follows, which can terminate thread in blocked state
and running state
:
1 |
|
Example of thread termination
interrupt()
is often used to terminate blocked
threads.
1 | public class InterruptDemo { |
Results:
1 | t1 (NEW) is new. |
The main thread
creates thread t1
through new MyThread("t1")
, and then starts thread t1 through t1.start()
.
After t1
starts, it will constantly check its interrupt flag. If the interrupt flag is false
, then sleep for 100ms.
After t1 sleeps
, it will switch to the main thread
. When the main thread
runs again, it will execute t1.interrupt()
to interrupt the thread t1
. After t1
receives the interrupt instruction, it will set the interrupt flag of t1
to false and an InterruptedException
will be thrown. In the run()
method of t1
, it is an exception caught outside the while of the loop body; therefore the loop is terminated.
We make a small modification to the above example and move the block of code that caught InterruptedException
in the run()
to the body of the while loop
1 | public class InterruptDemo2 { |
Results:
1 | t1 (NEW) is new. |
The program has entered an infinite loop!
Why is this so? This is because t1
is interrupted by interrupt()
while in the blocked state
. At this time, the interrupt flag will be cleared(isInterrupted ()
will return false
), and an InterruptedException
will be thrown. This exception is caught in the while loop. Therefore, t1
will naturally enter an endless loop.
To solve this problem, we need to additionally deal with the exit of the while loop when catching the exception. For example, adding break
or return
to MyThread
‘s catch(InterruptedException)
.
The following is an example of terminate a thread by additional flag.
1 | public class InterruptDemo3 { |
Results:
1 | t1 (NEW) is new. |
The difference between interrupted()
and isInterrupted()
Both interrupted()
and isInterrupted()
can be used to detect the interrupt flag
of an object.
The difference is that in addition to returning the interrupt flag
, interrupted()
will also clear the interrupt flag
(that is, set the interrupt flag
to false
). isInterrupted()
only returns the interrupt flag
.