子线程sleep的过程中, 给出中断信号的demo
当子线程正在休眠的过程中, 去进行线程的中断.
因此主线程要等子线程执行到 Thread.sleep(1000);这一行代码,因此在main线程中, 给出了Thread.sleep(500);
public class RightWayStopThreadWithSleep {
public static void main(String[] args) throws InterruptedException {
// 创建线程任务
Runnable runnable = () -> {
int num = 0;
try {
while (num <= 300 && !Thread.currentThread().isInterrupted()) {
if (num % 100 == 0) {
System.out.println(num + " 是100的整数");
}
num++;
}
//执行完成循环累加后, 执行sleep, 此时主线程给出中断信号
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
//启动线程
Thread thread = new Thread(runnable);
thread.start();
//当子线程 正在休眠的过程中, 去进行线程的中断.
//因此要等子线程执行到 Thread.sleep(1000);这一行代码
//此处的 Thread.sleep(500); 是给子线程 循环0到300的时间用的
Thread.sleep(500);
//子线程执行完成0到300累加后, 在子线程sleep的过程中, 去给出中断的信号
thread.interrupt();
}
}
程序执行的结果如下 :
可以看到 当子线程执行完循环的任务后 ,响应主线程的中断信号的方式为 抛出异常.
那是因为在子线程中, sleep方法被try catch所包裹了,
面对在sleep中,这种类似的阻塞操作的时候, 就会catch出这个异常, 打印如下的异常 ,响应中断
java.lang.InterruptedException: sleep interrupted
通过断点调试可以看到, 进入了catch的代码块.
而如果子线程没有阻塞的状态, 那么子线程即使收到了中断的信号, 也不会抛出异常.
线程在每次迭代时都阻塞的代码如下. 在子线程循环的过程中, 每次都Thread.sleep(10);
休眠10ms.
在子线程运行5s,后, 主线程给子线程发出中断的通知.
public class RightWayStopThreadWithSleepEveryLoop {
public static void main(String[] args) throws InterruptedException {
// 创建线程任务
Runnable runnable = () -> {
int num = 0;
try {
while (num <= 10000 && !Thread.currentThread().isInterrupted()) {
if (num % 100 == 0) {
System.out.println(num + " 是100的整数");
}
num++;
//每一次循环,休眠10ms
Thread.sleep(10);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
//启动线程
Thread thread = new Thread(runnable);
thread.start();
//此处的 Thread.sleep(5000); 是休眠主线程, 让子线程运行5s,
//子线程运行5s后, 给出子线程的休眠信号
Thread.sleep(5000);
thread.interrupt();
}
}
此时打印如下. 子线程打印出来sleep过程中被中断的异常
与上一节线程可能被阻塞的区别是, 此时由于每一次的循环,都会sleep, 因此真正判断子线程是否被中断, 不是使用Thread.currentThread().isInterrupted()
, 而是在Thread.sleep(10);
休眠的过程中, 就能立刻的感知到了中断通知, 就会抛出异常.
因此可以把代码修改如下, 在子线程的while (num <= 10000)
时, 就不需要进行判断线程是否中断了.
public class RightWayStopThreadWithSleepEveryLoop {
public static void main(String[] args) throws InterruptedException {
// 创建线程任务
Runnable runnable = () -> {
int num = 0;
try {
while (num <= 10000) {
if (num % 100 == 0) {
System.out.println(num + " 是100的整数");
}
num++;
//每一次循环,休眠10ms
Thread.sleep(10);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
//启动线程
Thread thread = new Thread(runnable);
thread.start();
//此处的 Thread.sleep(5000); 是休眠主线程, 让子线程运行5s,
//子线程运行5s后, 给出子线程的休眠信号
Thread.sleep(5000);
thread.interrupt();
}
}
打印的结果如下. 与加上判断线程是否中断的一致.
因此, 只要子线程在while循环的过程中, 每一次循环都会有让线程进行阻塞一段时间的情况下, 就不需要加上线程是否被中断的条件判断 .
因为会在阻塞的过程中,检测中断的状态, 并且抛出异常