如何停止一个线程,会发生什么事情?
- 通过自定义中断标识符
public class test1 {
// 自定义的中断标识符
private static volatile boolean isInterrupt = false;
public static void main(String[] args) throws InterruptedException {
// 创建可中断的线程实例
Thread thread = new Thread(() -> {
while (!isInterrupt) { // 如果 isInterrupt=true 则停止线程
System.out.println("thread 执行步骤1:线程即将进入休眠状态");
try {
// 休眠 1s
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread 执行步骤2:线程执行了任务");
}
});
thread.start(); // 启动线程
// 休眠 100ms,等待 thread 线程运行起来
Thread.sleep(100);
System.out.println("主线程:试图终止线程 thread");
// 修改中断标识符,中断线程
isInterrupt = true;
}
}
/**
* 输出:
* thread 执行步骤1:线程即将进入休眠状态
* 主线程:试图终止线程 thread
* thread 执行步骤2:线程执行了任务
*/
我们通过自定义标识符 isInterrupt
来判断,需要给该标识符加上 volatile 关键字
这种方式中断线程的执行就不太及时,比如我们先在 while 循环中判断是否中断,发现中断标识并没有中断,就进入到 while 循环中进行执行,那么此时主线程修改中断标识符,想要中断线程,线程内必须等 while 循环的这一轮执行完毕,才可以再次判断中断标识符是否需要中断,因此不够及时!
- interrupt 中断线程
通过调用线程的 interrupt()
方法,中断更及时
public class test1 {
public static void main(String[] args) throws InterruptedException {
// 创建可中断的线程实例
Thread thread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("thread 执行步骤1:线程即将进入休眠状态");
try {
// 休眠 1s
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("thread 线程接收到中断指令,执行中断操作");
// 中断当前线程的任务执行
break;
}
System.out.println("thread 执行步骤2:线程执行了任务");
}
});
thread.start(); // 启动线程
// 休眠 100ms,等待 thread 线程运行起来
Thread.sleep(100);
System.out.println("主线程:试图终止线程 thread");
// 修改中断标识符,中断线程
thread.interrupt();
}
/**
* 输出:
* thread 执行步骤1:线程即将进入休眠状态
* 主线程:试图终止线程 thread
* thread 线程接收到中断指令,执行中断操作
*/
}
扩展:
什么时候需要关闭一个线程?
- 多个线程同时抢一个东西,如果其中一个抢到了,那么需要通知关闭其他线程
- 线程一直去执行某一个任务,我们希望在限定时间拿到结果,如果限定时间内拿不到,就中断该线程
thread.interrupt() 方法调用后线程会立即中断吗?
不会,调用 interrupt 只是将被中断线程的中断状态设置为 true,通知被中断的线程自己处理中断,而不是立即强制的让线程直接中断(强制中断不安全)
当外部调用线程进行中断的命令时,如果该线程处于被阻塞的状态,如 Thread.sleep(),Object.wait(),BlockingQueue#put,BlockingQueue#take 等等时,那么此时调用该线程的 interrupt
方法就会抛出 InterruptedException
异常