download:借助产品思维解决人生难题(含实践方法论+分析工具)
在java中使用中断来通知线程停止
正常停止螺纹
公共类RightWayStopThreadWithoutSleep实现Runnable {
@覆盖
公共无效运行(){
int num = 0;
而(!Thread.currentThread()。isInterrupted() && num
if (num % 10000 == 0) {
System.out.println(num+"是1W的倍数");
}
num++;
}
System.out.println("任务完成了!");
}
公共静态void main(String[] args)引发InterruptedException {
Thread Thread = new Thread(new RightWayStopThreadWithoutSleep());
thread . start();
//等待1s
thread . sleep(1000);
//通知停止线程
thread.interrupt()。
}
}
复制代码
使用thread.interrupt()通知线程停止。
但是线程需要协作:
使用thread.currentthread()。isinterrupted () in while来检测线程的当前状态。
运行结果:
……
……
21730000是1W的倍数。
21740000是1W的倍数。
21750000是1W的倍数。
21760000是1W的倍数。
21770000是1W的倍数。
21780000是1W的倍数。
21790000是1W的倍数。
21800000是1W的倍数。
任务完成了!
进程结束,退出代码为0
复制代码
停止线程,以防它被阻塞。
公共类RightWayStopThreadWithSleep {
公共静态void main(String[] args)引发InterruptedException {
runnable runnable =()--> {
int num = 0;
while(数字
if (num % 100 == 0) {
System.out.println(num+"是100的倍数");
}
num++;
}
尝试{
//等待1秒模拟阻塞。
thread . sleep(1000);
} catch (InterruptedException e) {
System.out.println("线程已经停止!!");
e . printstacktrace();
}
};
Thread thread =新线程(runnable);
thread . start();
//等待时间应小于上面设置的1秒,否则线程会在执行到下一个thread.interrupt()之前结束;密码
thread . sleep(500);
//通知停止线程
thread.interrupt()。
}
}
复制代码
在线程休眠1秒的过程中,中断信号被中断,
在线程睡眠期间响应中断的方式是抛出InterruptedException。
运行结果:
是0到100的倍数。
00是100的倍数。
200是100的倍数。
30是100的倍数。
线程停止!!
中断异常:睡眠中断
at java.lang.Thread.sleep(原生方法)
在停止线程处。rightwaystopthreadwithsleep . lambda$main$0(rightwaystopthreadwithsleep . Java:19)
位于Java . lang . thread . run(thread . Java:748)
进程结束,退出代码为0
复制代码
每次迭代后用阻塞来停止线程。
公共类RightWayStopThreadWithSleepEveryLoop {
公共静态void main(String[] args)引发InterruptedException {
runnable runnable =()--> {
int num = 0;
尝试{
while(数字
if (num % 100 == 0) {
System.out.println(num+"是100的倍数");
}
num++;
//每个循环等待10ms以模拟阻塞
Thread.sleep(十);
}
} catch (InterruptedException e) {
e . printstacktrace();
}
};
Thread thread =新线程(runnable);
thread . start();
//5秒后通知停止线程
thread . sleep(5000);
thread.interrupt()。
}
}
复制代码
当每次迭代都会阻塞线程一段时间,判断while/for循环条件时,
不需要使用 thread.currentthread()。is interrupted () 确定线程是否中断。
运行结果:
是0到100的倍数。
00是100的倍数。
200是100的倍数。
30是100的倍数。
40是100的倍数。
中断异常:睡眠中断
复制代码
如果将上面代码中的try/catch放在while循环中
公共类RightWayStopThreadWithSleepEveryLoop {
公共静态void main(String[] args)引发InterruptedException {
runnable runnable =()--> {
int num = 0;
while(数字
if (num % 100 == 0) {
System.out.println(num+"是100的倍数");
}
num++;
尝试{
//每个循环等待10ms以模拟阻塞
Thread.sleep(十);
} catch (InterruptedException e) {
e . printstacktrace();
}
}
};
Thread thread =新线程(runnable);
thread . start();
//5秒后通知停止线程
thread . sleep(5000);
thread.interrupt()。
}
}
复制代码
运行结果:
是0到100的倍数。
00是100的倍数。
200是100的倍数。
30是100的倍数。
40是100的倍数。
中断异常:睡眠中断
at java.lang.Thread.sleep(原生方法)
在停止线程处。rightwaystopthreadwithsleepeveryloop . lambda$main$0(rightwaystopthreadwithsleepeveryloop . Java:18)
位于Java . lang . thread . run(thread . Java:748)
50是100的倍数。
60是100的倍数。
70是100的倍数。
……
……
复制代码
将会发现,尽管抛出了异常,程序并没有停止,而是继续输出,
即使加上了while条件判断!线程。当前线程()。是中断()条件,还是不能停止程序!
由于
Java在设计sleep()函数时就有这样的想法:
当它响应一个中断时,它将清除中断标志。
也就是说,线程虽然在睡眠时收到了中断通知,但也捕捉到了异常,并打印出了异常信息。
但是,由于睡眠的设计理念,线程。currentthread()。is interrupted()标志将被清除,
这就是程序不能退出的原因。
如果要在这里停止线程,只需要在catch中再次调用interrupt()即可;方法
尝试{
//每个循环等待10ms以模拟阻塞
Thread.sleep(十);
} catch (InterruptedException e) {
e . printstacktrace();
Thread.currentThread()。中断();
}
复制代码
所以,不要以为调用interrupt()方法线程就一定会停止。
停止线程的两种最佳方法
1.捕获InterruptedException后的首选项:在方法签名中引发异常。
公共类RightWayStopThreadInProd实现Runnable {
公共静态void main(String[] args)引发InterruptedException {
Thread Thread = new Thread(new RightWayStopThreadInProd());
thread . start();
thread . sleep(1000);
thread.interrupt()。
}
@覆盖
公共无效运行(){
while (true) {
System.out.println("go ... ");
尝试{
throwin method();
} catch (InterruptedException e) {
//捕捉异常,保存日志,停止程序等。
system . out . println(" stop ");
e . printstacktrace();
}
}
}
/**
*如果你想在一个方法中抛出一个异常,最好是抛出去,让顶层调用者来处理,而不是try/catch。
*以便调用者可以捕捉异常并执行其他操作。
- @throws中断异常
*/
私有void throwInMethod()引发InterruptedException {
线程.睡眠(2000年);
}
}
复制代码
如果你想在一个方法中抛出一个异常,最好抛出这个异常,让顶层调用者处理它,而不是try/catch。
通过这种方式,调用者可以捕获异常并采取其他操作。
2.调用thread.currentthread()。catch中的中断();恢复设置中断状态。
公共类RightWayStopThreadInProd2实现Runnable {
公共静态void main(String[] args)引发InterruptedException {
Thread Thread = new Thread(new rightwaystopthreadinprod 2());
thread . start();
thread . sleep(1000);
thread.interrupt()。
}
@覆盖
公共无效运行(){
while (true) {
if (Thread.currentThread()。isInterrupted()) {
System.out.println("程序运行结束");
打破;
}
reInterrupt();
}
}
私有void reInterrupt() {
尝试{
线程.睡眠(2000年);
} catch (InterruptedException e) {
Thread.currentThread()。中断();
e . printstacktrace();
}
}
}
复制代码
if (thread.currentthread()。is interrupted())这里的判断是你的代码要有响应中断的能力。
摘要
调用中断方法不一定会中断线程。
通知线程停止,线程不会立即停止,而是会在适当的时候停止。
代码应该能够响应中断。