本文内容部分引自《Java多线程编程核心技术》,感谢作者!!!
代码地址:https://github.com/xianzhixianzhixian/thread.git
停止线程的方法有以下几种
1、异常法:通过抛出异常来跳出正在运行的线程,在catch块中可以将异常向上层抛出,线程的停止事件得以传播。
2、沉睡法:通过Thread.sleep()一个很长的时间,让线程抛出java.lang.InterruptedException异常。
3、暴力法:直接通过Thread.stop()方法暴力中止线程,这是最不推荐的方法。stop之后有可能会导致线程一些清理性工作不能完成;同时对锁对象释放,数据不能被同步处理,有可能会导致数据不一致性问题。
4、return法:可以停止线程,但是与异常法相比更推荐异常法。
书中推荐的方法是异常法,因为这样在catch块中可以将异常向上层抛出,线程的停止事件得以传播。以下是例子
先运行一个反例,这样是不能停止线程的
MyThread.java
package thread.stop.exception;
/**
* 通过抛异常法来停止线程
* @author: xianzhixianzhixian
* @date: 2018-12-10 21:05
*/
public class MyThread extends Thread {
@Override
public void run() {
super.run();
for (int i=0;i<500000;i++){
if (this.isInterrupted()){
System.out.println("线程已停止,即将退出!");
break;
}
System.out.println("i="+(i+1));
}
System.out.println("如果代码在for之后又继续运行,表示线程未停止!");
}
}
Run.java
package thread.stop.exception;
/**
* @author: xianzhixianzhixian
* @date: 2018-12-10 21:10
*/
public class Run {
public static void main(String[] args) {
try {
MyThread thread = new MyThread();
thread.start();
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
}
System.out.println("end!");
}
}
结果如图所示,在break之后的输出语句还是运行到了,证明线程并未停止
那么应该怎么改变呢,其实只需要改变一行代码即可,将break;替换成throw new InterruptedException();
package thread.stop.exception;
/**
* 通过抛异常法来停止线程
* @author: xianzhixianzhixian
* @date: 2018-12-10 21:05
*/
public class MyThread extends Thread {
@Override
public void run() {
super.run();
try {
for (int i=0;i<500000;i++){
if (this.isInterrupted()){
System.out.println("线程已停止,即将退出!");
throw new InterruptedException();
}
System.out.println("i="+(i+1));
}
} catch (InterruptedException e) {
//在此处添加throw即可跳出正在运行的线程
System.out.println("进入MyThread.java中的异常捕获块了!");
e.printStackTrace();
}
}
}
运行结果如图,小伙伴是否弄清楚了呢: