sleep方法小知识点:
sleep方法在使用后,需要通过try-catch (InterruptedException)或者throws InterruptedException,不可以在重写run方法时抛出InterruptedException,这样违背了重写方法的规则。
通过Thread.sleep(time)可以使得当前线程阻塞time时间(ms)
package createThread.cn.tedu.threaddemo.test;
import java.util.Scanner;
/**
* 本例演示:线程在 sleep() 时被 interrupt() 中断,
* 会抛出 InterruptedException 并清除线程的中断标志位。
*
* 因此在 catch 中不做任何处理(不 break,也不重新设置中断标志),
* 外层 while (!cur.isInterrupted()) 会因为 isInterrupted() 返回 false 而继续执行,
* 导致子线程无法按预期中断退出。
*
* 正确做法:
* 1. 在 catch 中添加 break;
* 2. 或者调用 Thread.currentThread().interrupt() 重新设置中断标志位。
*/
public class Test {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
Thread cur = Thread.currentThread();
while (!cur.isInterrupted()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
System.out.println("thread 1");
}
System.out.println("子线程退出");
});
thread.start();
System.out.println("输入0终止线程");
Scanner scan = new Scanner(System.in);
int i = scan.nextInt();
if (i == 0) {
thread.interrupt();
System.out.println("主线程结束");
}
}
}
/**
* sleep() 被中断后,必须手动处理异常(break 或重新设置中断标志),否则线程会“误以为”没有被中断,从而继续执行下去!
*/
我们的目标是在输入0后立即中断thread线程,通过在main线程中,输出0 判断后,使用thread的方法interrupt()方法,来中断thread线程,所以在thread线程中因为存在Thread.sleep()在被中断后catch到了 InterruptedException异常,在打印了异常输出后,立即break结束掉了thread的循环从而结束了run方法从而结束了thread线程。

但是我们将break语句注释掉后

按理来说,我们在主线程main中输入了0,通过thread.interrupt()将thread中断了,为什么还能继续执行呢?
线程在 sleep() 时被 interrupt() 中断,
会抛出 InterruptedException 并清除线程的中断标志位。
因此在 catch 中不做任何处理(不 break,也不重新设置中断标志),
外层 while (!cur.isInterrupted()) 会因为 isInterrupted() 返回 false 而继续执行,
导致子线程无法按预期中断退出。
正确做法:
1. 在 catch 中添加 break;
2. 或者调用 Thread.currentThread().interrupt() 重新设置中断标志位。
465

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



