文章22 | 阅读 7590 | 点赞0
在 Java 中有三种方法可以使正在运行的线程终止:
下面我将对这三种方法分别进行举例说明。
在 run() 方法执行完毕后,线程就终止了,但是在某些特殊的情况下,run() 方法会被一直执行,此时就可以通过修改退出标志来结束 run() 方法,代码如下:
public class Run {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
myThread.start();
// 200 毫秒后终止线程
Thread.sleep(200);
myThread.flag = false;
}
}
class MyThread extends Thread {
private int i = 0;
public volatile boolean flag = true;
@Override
public void run() {
System.out.println("start");
while (flag) {
System.out.println("i = " + i++);
}
System.out.println("end");
}
}
首先要搞清楚一点,调用 interrupt() 方法仅仅是在当前线程中做了一个终止标记,并不会真正终止线程,如果想要真正终止线程,首先需要获取终止标记,然后根据终止标记的值来判断是否需要终止线程,那么如何获得终止标记的值呢?Java 提供了两个方法,部分源码如下:
public static boolean interrupted();
public boolean isInterrupted();
上述两个方法都可以获取线程终止标记的值,它们之间的区别如下:
下面我们通过例子来看一下两者的区别,调用 interrupted() 方法的代码如下:
public class Run {
public static void main(String[] args) {
System.out.println("当前线程是:" + Thread.currentThread().getName() + ",终止标记为:" + Thread.interrupted());
Thread.currentThread().interrupt();
System.out.println("当前线程是:" + Thread.currentThread().getName() + ",终止标记为:" + Thread.interrupted());
System.out.println("当前线程是:" + Thread.currentThread().getName() + ",终止标记为:" + Thread.interrupted());
}
}
控制台输出如下:
当前线程是:main,终止标记为:false
当前线程是:main,终止标记为:true
当前线程是:main,终止标记为:false
控制台第一行输出 false 是因为此时还没有调用 interrupt() 方法;第二行输出 true 是因为此时已经调用了 interrupt() 方法,终止标记被置为 true,但因为 interrupted() 方法具有清除功能,在每次调用 interrupted() 方法后终止标记都会被置为 false,所以第三行输出了 false。
调用 isInterrupted() 方法的代码如下:
public class Run {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
myThread.interrupt();
System.out.println("线程:" + myThread.getName() + "的终止标记为:" + myThread.isInterrupted());
System.out.println("线程:" + myThread.getName() + "的终止标记为:" + myThread.isInterrupted());
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Hello World!");
}
}
控制台输出如下:
线程:Thread-0的终止标记为:true
线程:Thread-0的终止标记为:true
Hello World!
因为 isInterrupted() 方法不具备清除终止标记的功能,所以在调用了 interrupt() 方法后,两次输出都为 true。
在学会怎么获取终止标记后,我们就可以通过终止标记的值来判断什么时候终止线程了,下面直接上案例代码:
public class Run {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
myThread.start();
Thread.sleep(10);
myThread.interrupt();
}
}
class MyThread extends Thread {
@Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
if (this.isInterrupted()) {
System.out.println("此时已经是终止状态了,我要退出了!");
throw new InterruptedException();
}
System.out.println("i = " + (i + 1));
}
} catch (InterruptedException e) {
System.out.println("我已经退出了!");
e.printStackTrace();
}
}
}
控制台输出部分代码如下:
i = 372
i = 373
i = 374
i = 375
i = 376
i = 377
i = 378
此时已经是终止状态了,我要退出了!
我已经退出了!
java.lang.InterruptedException
at t006.MyThread.run(Run.java:19)
如果 interrupt() 和 sleep() 方法碰到一起会出现什么情况呢?
答:会抛出 java.lang.InterruptedException 异常,无论是先执行 interrupt() 方法还是先执行 sleep() 方法都会抛出异常。
使用 stop() 方法可以强行停止线程,这种方法方法过于暴力,使用时可能造成不可预料的结果,现在已经被废弃,但我们还是需要简单了解一下,下面通过一段代码来初步了解 stop() 方法的使用,代码如下:
public class Run {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
myThread.start();
// 让 main 线程等待 8 秒
Thread.sleep(8000);
myThread.stop();
}
}
class MyThread extends Thread {
private int i = 0;
@Override
public void run() {
try {
while (true) {
i++;
System.out.println("i=" + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
控制台输出如下:
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
代码逻辑很简单,我就不做解释了。
调用 stop() 方法时会抛出 java.lang.ThreadDeath 异常,但在通常情况下,此异常不需要显示地捕捉。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_41685207/article/details/108889842
内容来源于网络,如有侵权,请联系作者删除!