线程中止的三种方式:
1、stop()
此方式已被弃用,因为无法保证同步代码块的原子性,实例代码如下:
public class ThreadStop {
public static void main(String[] args) throws InterruptedException {
StopThread t = new StopThread();
t.start();
//休眠一秒确保 i 自增成功
Thread.sleep(1000);
//暂停线程
t.stop(); //被弃用的方式
// t.interrupt(); //推荐方式
//确保线程已经终止
while(t.isAlive()) {}
t.print();
}
}
class StopThread extends Thread {
private int i = 0, j = 0;
@Override
public void run() {
synchronized (this) {
i++;
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
j++;
}
}
public void print() {
System.out.println("i=" + i + ", j=" + j);
}
}
输出
i=1, j=0
2、interrupt()
如果目标线程在调用Object class的wait、join、sleep方法后,线程阻塞情况下,interrupt会生效,此时会清除线程的睡眠或等待状态,让线程继续执行保证原子性,但会抛出InterruptedException异常。
如果目标线程是被I/O或者NIO的channel阻塞,interrupt也会生效,I/O操作会被中断或者返回特殊异常值,达到终止线程的目的。
如果以上情况都不满足,interrupt方法会为线程设置中断标志位。
相比stop()方法可以在保证原子性的基础上,抛出InterruptedException异常,由开发者捕获后自行处理。示例代码如下:
public class ThreadStop {
public static void main(String[] args) throws InterruptedException {
StopThread t = new StopThread();
t.start();
//休眠一秒确保 i 自增成功
Thread.sleep(1000);
//暂停线程
// t.stop(); //被弃用的方式
System.out.println("是否被中断:" + t.isInterrupted());
t.interrupt(); //推荐方式
System.out.println("是否被中断:" + t.isInterrupted());
//确保线程已经终止
while(t.isAlive()) {}
t.print();
}
}
class StopThread extends Thread {
private int i = 0, j = 0;
@Override
public void run() {
synchronized (this) {
i++;
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("捕获到异常:" + e.getMessage());
}
j++;
}
}
public void print() {
System.out.println("i=" + i + ", j=" + j);
}
}
输出
是否被中断:false
是否被中断:true
捕获到异常:sleep interrupted
i=1, j=1
3、使用标志位
此方法通过设置标志位,达到中止线程的目的,但受制于具体业务,代码如下:
public class StopThreadDemo extends Thread {
public volatile static boolean flag = true;
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
try {
while(flag) {
System.out.println("运行中...");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
//3秒后,将标志位改为 false,中止线程
Thread.sleep(3000);
flag = false;
System.out.println("程序运行结束。");
}
}
输出
运行中...
运行中...
运行中...
程序运行结束。