Java 中有以下三种停止线程的方法:
- 使用 退出标志,使线程正常退出,也就是当 run 方法完成后终止线程。
- 使用 stop 方法 强行退出,但是不推荐这个方法,因为 stop 和 suspend 及 resume 一样,都是作废过期的方法,使用它们可能产生不可预料的后果(后文有详细说明)。
- 使用 interrupt 方法 中断线程
停不了的线程
本示例将调用 interrupt() 方法来停止线程,但 interrupt() 方法的使用效果并不像 for+break 语句那样,马上就停止循环。调用 interrupt() 方法仅仅是在当前线程中打上一个停止标记,并不是真正停止线程。
public class t11 {
public static void main(String[] args) {
try {
Mythread thread = new Mythread();
thread.start();
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Mythread extends Thread {
public void run() {
for(int i=0; i<50000; i++){
System.out.println("i = "+i);
}
}
}

正如你所看到的,interrupt() 方法并没有停止线程。那么我们应该如何让线程停止呢?
注:如果你不是很清楚 interrupted() 和 isInterrupted() 的区别 请先阅读我的这篇博客 interrupted() 和 isInterrupted() 的区别
能停止的线程——异常法
当线程调用 interrupt 后,会将状态标志(是否中断)修改成为 true,那么我们就可以在线程中用 if 语句判断一下线程是否是停止状态,如果是停止状态,则后面代码不再运行即可。
public class t15 {
public static void main(String[] args) {
try {
Thread thread = new MyThread15();
thread.start();
Thread.sleep(1000);
thread.interrupt();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("------------- main end -------------");
}
}
class MyThread15 extends Thread{
public void run(){
for (int i = 0; i < 500000; i++) {
if(this.interrupted()){
System.out.println("已经停止状态了!我要退出了!!!");
break;
}
System.out.println("i= "+ i);
}
System.out.println("------------ 我是 thread 的 end --------------");
}
}

你可以看到,虽然线程停止了,但是如果 for 下面还有语句的话线程还是会继续执行。那么我们需要改进下代码,让线程直接结束掉。
package com.thread.interrupt;
public class t16 {
public static void main(String[] args) {
try {
Thread thread = new MyThread16();
thread.start();
Thread.sleep(1000);
thread.interrupt();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("------------- main end -------------");
}
}
class MyThread16 extends Thread{
public void run(){
try {
for (int i = 0; i < 500000; i++) {
if(this.interrupted()){
System.out.println("已经停止状态了!我要退出了!!!");
throw new InterruptedException();
}
System.out.println("i= "+ i);
}
System.out.println("------------ 我是 thread 的 end --------------");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

使用 return 停止线程
将 interrupt() 方法与 return 结合也能实现停止线程的效果
public class t18 {
public static void main(String[] args) {
try {
Thread thread = new MyThread18();
thread.start();
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class MyThread18 extends Thread {
public void run() {
while (true) {
if (interrupted()) {
System.out.println("停止了!!!");
return;
}
System.out.println(1);
}
}
}

虽然线程停止了,但是还是建议使用抛出异常的方式来停止线程,因为在 catch 块中可以对异常的信息进行相关处理,而且使用异常流能更好、更方便的控制程序运行流程,不至于代码中出现多个 return; 造成污染。
能停止的线程——暴力停止
使用 stop() 方法停止线程是非常暴力的。
public class t17 {
public static void main(String[] args) {
try {
Mythread11 thread = new Mythread11();
thread.start();
Thread.sleep(2000);
thread.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Mythread17 extends Thread {
public void run() {
int i = 0;
while (true) {
System.out.println("i = " + i++);
}
}
}

线程戛然而止。而且会伴随着一些列问题:
- 调用 stop() 方法会抛出 java.lang.ThreadDeth 异常。
- 调用 stop() 方法会释放锁资源,导致数据不一致性产生。
本文介绍了Java中三种停止线程的方法:使用退出标志使线程正常退出、使用stop方法强行退出(不推荐)、使用interrupt方法中断线程。并通过示例演示了如何正确使用interrupt方法配合异常处理来安全地停止线程。
2062

被折叠的 条评论
为什么被折叠?



