当前位置:网站首页>Concurrent programming - how to interrupt / stop a running thread?
Concurrent programming - how to interrupt / stop a running thread?
2022-07-05 07:04:00 【Handling Gong】
How to interrupt or stop a running thread correctly ? This is a very classic interview question , It covers a lot of knowledge points , After reading this article , Take you to thoroughly master the correct interruption 、 Methods to stop threads .
What is interrupt mechanism ?
First
A thread should not be forced to interrupt or stop by other threads , It is The thread should stop itself , Decide your own destiny .
therefore ,Thread.stop,Thread.suspend,Thread.resume It's been abandoned .
secondly
stay Java There is no way to stop a thread immediately , However, stopping threads is particularly important , For example, cancel a time-consuming operation . therefore ,Java Provides a negotiation mechanism for stopping threads -- interrupt , That is, interrupt identification negotiation mechanism .Interruption is just a collaborative negotiation mechanism ,Java No syntax added to interrupt , The interruption process needs to be implemented by the programmer himself .
To interrupt a thread , You need to manually call the thread's interrupt Method , This method only sets the interrupt ID of the thread object to true;
Then you need to write your own code to constantly detect the identification bit of the current thread , If true, Indicates that another thread requests this thread to interrupt .What to do at this time requires you to write your own code to realize .
Each thread object has an interrupt identifier bit , Used to indicate whether a thread is interrupted , The identification bit is true To interrupt , by false Means not interrupted ;
By calling the interrupt Method to set the identification bit of the thread to true; Can be invoked in other threads , You can also call it in your own thread .
Threads (Thread class ) Interrupted API Method
Since there is a business scenario of thread interruption , that Java The Bulls must also have thought of , And the corresponding API Method to accomplish , Let's take a look at what they have , How are they realized .
void interrupt()
Example method , Just set the interrupt status of the thread to true, Initiate a negotiation without immediately stopping the thread .
static boolean interrupted()
Static methods ,Thread.interrupted();
Determine whether the thread is interrupted and clear the current interrupt state .
This method does two things :
1. Returns the interrupt status of the current thread , Tests whether the current thread has been interrupted
2. Clear the interrupt state of the current thread and reset it to false, Clear the interrupt state of the thread
This method is a little difficult to understand , If you call this method twice in a row , The second call will return false, Because the results of two consecutive calls may be different
boolean isInterrupted()
Example method
Determine whether the current thread is interrupted ( Check the interrupt flag bit )
How to stop interrupting a running thread ?
1. adopt volatile Set shared variables
public class InterruptedDemo {
/**
* Thread interrupt flag bit
*/
static volatile boolean stopFlag = false;
public static void main(String[] args) {
new Thread(() -> {
while (true) {
if (stopFlag) {
System.out.println(Thread.currentThread().getName() + " Thread the interrupt , Stop running !");
break;
}
System.out.println(Thread.currentThread().getName() + " Thread start , Start moving bricks ...");
}
},"t1").start();
try { TimeUnit.MILLISECONDS.sleep(1L); } catch (InterruptedException e) { e.printStackTrace(); }
// The main thread tells t1 Threads , Need to interrupt
stopFlag = true;
}
}
2. AtomicBoolean Atomic classes
static AtomicBoolean atomicBoolean = new AtomicBoolean(false);
public static void main(String[] args) {
new Thread(() -> {
while (true) {
if (atomicBoolean.get()) {
System.out.println(Thread.currentThread().getName() + " Thread the interrupt , Stop running !");
break;
}
System.out.println(Thread.currentThread().getName() + " Thread start , Start moving bricks ...");
}
},"t1").start();
try { TimeUnit.MILLISECONDS.sleep(1L); } catch (InterruptedException e) { e.printStackTrace(); }
// The main thread tells t1 Threads , Need to interrupt
atomicBoolean.set(true);
This and the above volatile equally , The same thing can be done .
3. Thread API
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().getName() + " Thread the interrupt , Stop running !");
break;
}
System.out.println(Thread.currentThread().getName() + " Thread start , Start moving bricks ...");
}
},"t1");
t1.start();
try { TimeUnit.MILLISECONDS.sleep(1L); } catch (InterruptedException e) { e.printStackTrace(); }
// t2 Thread notification t1 Thread interrupt
new Thread(() -> t1.interrupt(),"t2").start();
}
4. interrupt()、isInterrupted() Source code analysis
Called the underlying native Method interrupt0(), Just set a sign .
Reset flag bit to false.
By looking at the source code , The conclusion is as follows :
When it comes to a thread , call interrupt() when :
① If the thread is in Normal active state , The thread's interrupt flag will be set to true, That's it .The thread with interrupt flag will continue to run normally , Unaffected .
therefore ,interrupt() It doesn't really interrupt threads , You need to cooperate with the called thread .② If the thread is blocked ( For example, in the sleep、wait、join Equal state ), To call the current thread object in another thread interrupt Method , Then the thread will immediately exit the blocked state , And throw a InterruptedException abnormal .
Here's a simple case Let's demonstrate the conclusion :
- Verify that the interrupt command is issued to the thread interrupt after , The interrupt will not be executed immediately
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 200; i++) {
System.out.println("----> " + i);
}
// here , verification t1 Whether the thread receives the interrupt request , The execution of the output here is terminated immediately ?
System.out.println("t1 Interrupt flag bit of thread 02 --> " + Thread.currentThread().isInterrupted()); // true
},"t1");
t1.start();
System.out.println("t1 The default interrupt flag bit of the thread --> " + t1.isInterrupted()); // false
try { TimeUnit.MILLISECONDS.sleep(1L); } catch (InterruptedException e) { e.printStackTrace(); }
// Send thread interrupt request
t1.interrupt();
System.out.println("t1 Interrupt flag bit of thread 01 --> " + t1.isInterrupted()); // true
try { TimeUnit.MILLISECONDS.sleep(500L); } catch (InterruptedException e) { e.printStackTrace(); }
// here ,t1 Thread has ended , Return to the default state
System.out.println("t1 Interrupt flag bit of thread 03 --> " + t1.isInterrupted()); // false
}
t1 After thread execution , Get the interrupt identification bit of the thread for the second time through the output of the console , Also time true.
When our main thread sleeps 500 ms after ,t1 The thread has finished executing , End of life cycle , At this time, the third acquisition t1 Interrupt identification bit of thread , It's changed into false. It verifies our conclusion : For inactive threads , Interrupt request defaults to false.
- Verify that it is blocked , Calling the interrupt method throws an exception
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().getName() + " Thread the interrupt !!");
break;
}
System.out.println("----> validate InterruptedException..");
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
// After throwing an exception , The interrupt ID of the thread will be cleared , Reset to default ,
// therefore , If you don't add this line of code , There will be an endless cycle , Other thread pairs t1 The interrupt request sent by the thread failed
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
}, "t1");
t1.start();
try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); }
// Send thread interrupt request
t1.interrupt();
}
- static boolean interrupted() Static method description
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + " Thread interrupt status 01 ----> " + Thread.currentThread().isInterrupted());
/**
* Thread.interrupted() Static methods , Did two things
* 1. Returns the interrupt status of the current thread , Tests whether the current thread has been interrupted
* 2. Clear the interrupt state of the current thread and reset it to false, Clear the interrupt state of the thread
*/
Thread.currentThread().interrupt();
System.out.println("====== Send interrupt request =======");
System.out.println(Thread.currentThread().getName() + " Thread interrupt status 02 ----> " + Thread.currentThread().isInterrupted());
System.out.println(Thread.currentThread().getName() + " Thread interrupt status 03 ----> " + Thread.interrupted());
System.out.println(Thread.currentThread().getName() + " Thread interrupt status 04 ----> " + Thread.currentThread().isInterrupted());
}
Take a look at the source code :
It can be seen that , Static method and instance method , In fact, they all call the same native Method , But the parameters passed in are different , One is to reset the state , One is not needed .
I believe through the above content , Children's shoes have a deeper understanding of interrupt threads !
边栏推荐
猜你喜欢
随机推荐
Pycahrm reports an error: indentation error: unindent does not match any outer indentation
使用paping工具进行tcp端口连通性检测
Volcano resource reservation feature
testing framework
Matlab在线性代数中的应用(四):相似矩阵及二次型
Integer to 8-bit binary explanation (including positive and negative numbers) scope of application -127~+127
摄像头的MIPI接口、DVP接口和CSI接口
Dameng database all
[tf] Unknown: Failed to get convolution algorithm. This is probably because cuDNN failed to initial
【obs】x264编码:“buffer_size“
Marvell 88E1515 PHY loopback模式测试
数学分析_笔记_第8章:重积分
Configuration method and configuration file of SolidWorks GB profile library
[nvidia] CUDA_ VISIBLE_ DEVICES
mingling
SD_CMD_RECEIVE_SHIFT_REGISTER
Ros2 - first acquaintance with ros2 (I)
inux摄像头(mipi接口)简要说明
In C language, int a= 'R'
Mipi interface, DVP interface and CSI interface of camera