现在提供一下线程中断的几种方法
- Stop() 方法
stop() 废弃方法,开发中不要使用。因为一调用,线程就立刻停止,此时有可能引发相应的线程安全性问题
下面根据代码来具体看一下:
public class UnSaveWithStopDemo extends Thread {
private int i = 0;
private int j = 0;
@Override
public void run() {
i++;
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
j++;
}
public void printf() {
System.out.println("i的值=====" + i);
System.out.println("j的值=====" + j);
}
public static void main(String[] args) throws InterruptedException {
UnSaveWithStopDemo myThread = new UnSaveWithStopDemo();
myThread.start();
Thread.sleep(1000L);
myThread.stop();
myThread.printf();
}
}
最终输出为:,
这个与我们的预期:j=1,i=1,就不相符了。
- interrup
线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态,即设置为true。中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。它并不像stop方法那样会中断一个正在运行的线程。
public void run() {
try {
...
/*
* 不管循环里是否调用过线程阻塞的方法如sleep、join、wait,这里还是需要加上
* !Thread.currentThread().isInterrupted()条件,虽然抛出异常后退出了循环,显
* 得用阻塞的情况下是多余的,但如果调用了阻塞方法但没有阻塞时,这样会更安全、更及时。
*/
while (!Thread.currentThread().isInterrupted()&& more work to do) {
do more work
}
} catch (InterruptedException e) {
//线程在wait或sleep期间被中断了
} finally {
//线程结束前做一些清理工作
}
}
上面是while循环在try块里,如果try在while循环里时,因该在catch块里重新设置一下中断标示,因为抛出InterruptedException异常后,中断标示位会自动清除,此时应该这样:
public void run() {
while (!Thread.currentThread().isInterrupted()&& more work to do) {
try {
...
sleep(delay);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();//重新设置中断标示
}
}
}
底层中断异常处理方式
不要在你的底层代码里捕获InterruptedException异常后不处理,会处理不当,如下:
void run(){
...
try{
sleep(delay);
}catch(InterruptedException e){}//不要这样做
...
}
如果你不知道抛InterruptedException异常后如何处理,那么你有如下好的建议处理方式:
1、在catch里面设置Thread.currentThread().interrupt(),设置中断标志,让外界通过判断Thread.currentThread().isInterrupted()标示来决定是否终止线程还是继续下去,应该这样做:
void mySubTask() {
...
try {
sleep(delay);
} catch (InterruptedException e) {
Thread.currentThread().isInterrupted();
}
...
}