Java-interrupt方法的一个小的注意点
记录Java 中 interupt()
方法的一个小的知识点。
开发过程中,经常有需要去终止线程,终止线程的方式无外乎有两种 标志位 或 interrupt(), 前者没什么好说的,就是定义一个bool类型的变量,只是需要注意将该变量声明成 volatile
。后者的话主要用于终止带阻塞状态的线程,当然也可以用来终止不带阻塞状态的线程,这里再来复习一下:
关于终止线程的介绍,可参考:Java: Java终止线程的几种方式
终止不带阻塞状态的线程
TaskCase.java
package com.yongdaimi.dmeo;
public class TaskCase {
private Thread mTaskThread;
public void start() {
mTaskThread = new Thread() {
@Override
public void run() {
super.run();
System.out.println(Thread.currentThread().getName()+" start running...");
// 模拟重复执行的任务
while (!Thread.currentThread().isInterrupted()) {
System.out.println("doSomething");
}
System.out.println(Thread.currentThread().getName()+" stop running...");
}
};
mTaskThread.start();
}
/**
* 使用此方法进行终止
*/
public void calcel() {
mTaskThread.interrupt();
}
}
Test.java
package com.yongdaimi.dmeo;
public class Test {
public static void main(String[] args) {
TaskCase task = new TaskCase();
task.start();
// 2s 后将测试线程终止
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
task.calcel();
}
}
运行:
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
doSomething
Thread-0 stop running...
可以看到使用此方法,2秒后是可以将执行线程正常终止的。
那如果加了阻塞状态呢?
TaskCase.java
package com.yongdaimi.dmeo;
public class TaskCase {
private Thread mTaskThread;
public void start() {
mTaskThread = new Thread() {
@Override
public void run() {
super.run();
System.out.println(Thread.currentThread().getName()+" start running...");
// 模拟重复执行的任务
while (!Thread.currentThread().isInterrupted()) {
System.out.println("doSomething");
// 模拟阻塞 500ms
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" stop running...");
}
};
mTaskThread.start();
}
/**
* 使用此方法进行终止
*/
public void calcel() {
mTaskThread.interrupt();
}
}
这里在线程中添加一段code, 使线程临时阻塞500ms, 再次执行:
这时发现虽然有走到异常的代码块里,但是线程仍然能够正常执行,没有退出,Why? 这是因为:
「注意:发生异常时线程的中断标志为会由true更改为false。」
所以最好这样写成这样:
// 模拟重复执行的任务
while (!Thread.currentThread().isInterrupted()) {
System.out.println("doSomething");
// 模拟阻塞 500ms
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
// 重置中断标志位为true
Thread.currentThread().interrupt();
}
}
在出现异常后,重置中断标志位,这样再次执行后,就可以顺利中断线程了:
当然也可以在出现异常时,直接使用return语句终止,那样也是可以的,今天在是review一个同事的code时发现了此问题,所以记录一下。
参考链接:
为什么说volatile+interrupt是停止线程最优雅的姿势?
标签:Java,Thread,doSomething,currentThread,线程,注意,interrupt,public,mTaskThread From: https://www.cnblogs.com/yongdaimi/p/16969091.html