-
2020-05-20 14:16:38
参考文档
https://blog.csdn.net/blog_empire/article/details/86693851
1.demo
package com.br.doublelive.redis; import javafx.concurrent.Worker; public class InterruptExceptionTest { public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new Worker()); t.start(); Thread.sleep(100); t.interrupt(); System.out.println("Main thread stopped."); } public static class Worker implements Runnable { @Override public void run() { System.out.println("Worker started."); try { Thread.sleep(200); } catch (InterruptedException e) { System.out.println("抛出异常JVM会清除线程的中断状态 Worker IsInterrupted--------: " + Thread.currentThread().isInterrupted()); // TODO: 2019/1/29 对抛出的InterruptedException的正确处理应该是设置Thread.currentThread().interrupt(); Thread.currentThread().interrupt(); System.out.println("执行interrupt()设置线程的中断状态 Worker IsInterrupted--------: " + Thread.currentThread().isInterrupted()); /** * 清除线程的中断状态 */ Thread.interrupted(); System.out.println("清除线程的中断状态interrupted(); Worker IsInterrupted--------: " + Thread.currentThread().isInterrupted()); } System.out.println("Worker stopped."); } } }
2.以上代码执行结果
Worker started. 抛出异常JVM会清除线程的中断状态 Worker IsInterrupted--------: false 执行interrupt()设置线程的中断状态 Worker IsInterrupted--------: true 清除线程的中断状态interrupted(); Worker IsInterrupted--------: false Worker stopped. Main thread stopped.
3.如果把Thread.interrupted();注释掉
Worker started. Main thread stopped. 抛出异常JVM会清除线程的中断状态 Worker IsInterrupted--------: false 执行interrupt()设置线程的中断状态 Worker IsInterrupted--------: true 清除线程的中断状态interrupted(); Worker IsInterrupted--------: true Worker stopped.
4.如果把Thread.currentThread().interrupt()注释掉
Worker started. Main thread stopped. 抛出异常JVM会清除线程的中断状态 Worker IsInterrupted--------: false 执行interrupt()设置线程的中断状态 Worker IsInterrupted--------: false 清除线程的中断状态interrupted(); Worker IsInterrupted--------: false Worker stopped.
更多相关内容 -
Thread.sleep()为什么要抛出中断异常
2021-08-22 10:47:05假设sleep()方法不抛出中断异常,也就是线程没有中断响应能力,会怎么样? 考虑如下场景: 线程A:sleep中 线程B:A别睡了,要关机啦(向A发送中断信号) 线程A:sleep中 这样好吗?这不好。因为线程A对外界...当然是为了让你的代码具有响应中断信号的能力!
目录
从场景说起
假设sleep()方法不抛出中断异常,也就是线程没有中断响应能力,会怎么样?
考虑如下场景:
线程A:sleep中
线程B:A别睡了,要关机啦(向A发送中断信号)
线程A:sleep中
这样好吗?这不好。因为线程A对外界情况没有感知能力。
中断就起到了这样的作用:让线程具有感知的能力。sleep(),wait()等方法都需要你去处理中断异常,也就是需要你的代码能够响应中断。
响应中断
什么叫能够响应中断呢?下面这段最常见的代码可以响应吗?
try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }
答案是可以响应,但还不够。为什么呢?
如下图,官方文档说了:抛异常的同时,该线程的中断状态会被清除。
那中断状态清除了,有什么影响吗?
当然有,我们一般代码都会这样写:(目的:休眠100毫秒后,判断线程是否被中断,如果未被中断则继续执行业务)
try { Thread.sleep(100); } catch (InterruptedException e) { //中断标志已经被清除了 } // Thread.currentThread().isInterrupted():是否被中断了(是否有中断标志) if(!Thread.currentThread().isInterrupted()) { //如果没有被中断,则处理业务 doSomething(); }
如果你运行起来会发现,即使线程在sleep期间被中断,我们下面的代码依然会执行。为什么呢?就是因为sleep是会擦除中断标志的。
那你可能会说:我为什么要写if(!Thread.currentThread().isInterrupted())呢?我平时都不判断的。
首先这是个demo,主要是展示效果。其次,我们任何代码都要有响应中断的能力,所以一般加个while(!Thread.currentThread().isInterrupted())。
回到上面的demo,如果要实现休眠100毫秒后,判断线程是否被中断,如果未被中断则继续执行业务该怎么办?
很简单,我们在本线程再中断一次即可。代码如下:
try { Thread.sleep(100); } catch (InterruptedException e) { //中断标志已经被清除了 // 手动中断本线程,将本线程打上中断信号。 Thread.currentThread().interrupt(); } // Thread.currentThread().isInterrupted():是否被中断了(是否有中断标志) if(!Thread.currentThread().isInterrupted()) { //如果没有被中断,则处理业务 doSomething(); }
如上述代码所示,我们手动调用interrupt()方法即可。这样业务代码就不会执行了。
关闭线程池
可能上述理论你还是有些懵。下面进入实战环节。
那么我们看看线程池如何关闭?
有两个API:
void shutdown():等待队列和当前执行的任务会继续执行完。
List<Runnable> shutdownNow():对所有正在执行的任务线程发送中断信号。等待队列的任务会被返回。
这下你知道为什么我们代码需要有响应中断的能力了吗?我们先举一个无法停掉线程的例子:
ExecutorService executorService = Executors.newFixedThreadPool(1); executorService.execute(()->{ //任务一直跑 while (true) { System.out.println("1"); } }); Thread.sleep(10); executorService.shutdownNow();
你看,我们根本无法停掉任务,根本无法关闭线程池!
所以while(!Thread.currentThread().isInterrupted())才对嘛。
怎么关呢?代码我就不写了,关键点如下:
1.你的代码一定要有响应中断的能力。
2.sleep等方法就有这个能力。但是他会擦除中断标志位,记得调用Thread.currentThread().interrupt()恢复中断标志位哦。
-
PowerMockito模拟Thread.sleep()时抛出中断异常的场景
2021-03-22 12:44:24并且我已经成功开通了流量主同时会赚一点点广告费,我打算每个月把这部分钱拿出来给大家买点书刊,算是给... 想要在单元测试时,模拟Thread.sleep()时抛出中断异常的行为,但是仅使用PowerMockito.mockStatic(Thread...点击蓝色字
免费订阅,每天收到这样的好信息
前言:最近有不少粉丝关注本公众号。并且我已经成功开通了流量主同时会赚一点点广告费,我打算每个月把这部分钱拿出来给大家买点书刊,算是给大家一点福利吧。大家想买什么书扫描下方的加他拉你加群。最后,非常感谢大家的关注。
想要在单元测试时,模拟Thread.sleep()时抛出中断异常的行为,但是仅使用PowerMockito.mockStatic(Thread.class)是不够的,上代码:
要测试的方法getResult:
public class Weekend{public void getResult() throws InterruptedException{try {Thread.sleep(2000);} catch(InterruptedException e) {throw e;}}}
WeekendTest文件
@RunWith(PowerMockRunner.class)// 此处为实际执行 Thread.sleep()的类 Weekend.class,而不是 Thread.class@PrepareForTest(Weekend.class)public class WeekendTest {@InjectMocksprivate Weekend weekend;@Test(expected = InterruptedException.class)public void testGetResult() throws InterruptedException {PowerMockito.mockStatic(Thread.class);PowerMockito.doThrow(new InterruptedException()).when(Thread.class);Thread.sleep(anyLong());weekend.getResult();}}
代码运行结果:
需要注意的是,通常我们mock静态方法时,是在@PrepareForTest注解中,加上对应类名,如:
@PrepareForTest(Utils.class)public class Test{public void testFunction() {PowerMockito.mockStatic(Utils.class);PowerMockito.when(Utils.function()).thenReturn(expectedResult);}}
但是对于Thread.sleep方法,在@PrepareForTest中加入Thread.class是无效的,必须加入实际调用Thread.sleep()方法的类,本例中为Weekend.class. 如果没有在@PrepareForTest中加入实际调用类,则无法抛出异常。
打油诗
我不在乎我的作品文章是被现在的人读还是由子孙后代来读。既然上帝花了六千年来等一位观察者,我可以花上一个世纪来等待读者。
-
问九:源码层面解析Thread.sleep()为什么需要抛异常?
2019-05-01 10:15:05结合此篇文章进行阅读:...Thread.sleep()抛的是InterruptedException,这个错误在源码中的注释为: * Thrown when a thread is waiting, sleeping, orotherwise occupied, * and the thread is interrupted, e...结合此篇文章进行阅读:InterruptedExcption详细分析
导入:
Thread.sleep()抛的是InterruptedException,这个错误在源码中的注释为:
* Thrown when a thread is waiting, sleeping, or otherwise occupied,
* and the thread is interrupted, either before or during the activity.
* Occasionally a method may wish to test whether the current
* thread has been interrupted, and if so, to immediately throw
* this exception.
概述:
这个问题实际上是对interrupt方法的一个升级版,先解释interrupt,再解释源码中的判断
源码分析:
通过查看sleep的源码发现,它其实是一个native方法,参考前面run与start区别,来进行源码查找与分析
jvm源码:
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/111b95ad4584/src/share/vm/prims/jvm.cpp
Thread中native方法的源码,调用了JVM_Sleep方法:
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/f0b93fbd8cf8/src/share/native/java/lang/Thread.c
可以看到,sleep这个方法在源码中是会判断当前进程是否处于interrupted状态的,也符合之前所所说的interrupt方法需要调用的线程支持
-
java – 为什么需要处理Thread.sleep()的异常?
2021-03-04 06:28:30如果以一种方式声明方法可以抛出已检查的异常(异常不是RuntimeException的子类),调用它的代码必须在try-catch块中调用它,或者调用方法必须声明抛出它.public static void sleep(long millis) throws ... -
Thread.sleep() 和 TimeUnit.SECONDS.sleep() 该如何选择?
2021-11-25 14:10:16前两天在研究线程的时候发现了一个比较好用的类 TimeUnit 类,今天来记录一下和 Thread.sleep() 的区别,同时也是为了我们另一篇文章做了一些铺垫 -
Thread.sleep() 和 TimeUnit.SECONDS.sleep()的关系
2019-10-22 20:07:53(1)Thread.sleep() 和 TimeUnit.SECONDS.sleep()均实现线程暂停操作; (2)TimeUnit枚举成员的方法提供更好的可读性,通常用来替换Thread.sleep(); 例如同样实现线程暂停3分钟: Thread.sleep(180000);或Th... -
Java的Thread.sleep何时会引发InterruptedException?
2021-02-28 08:50:51不要吞下中断有时,抛出InterruptedException并不是一种选择,例如Runnable定义的任务调用可中断方法时。在这种情况下,您不能抛出InterruptedException,但也不想执行任何操作。当阻塞方法检测到中断并引发... -
Thread.sleep()的InterruptedException处理
2020-06-05 14:43:19public class OOMTest { public static void main(String[] args) { Thread thread = new Thread(new Runnable() { @Override public void run() { ... //1.sleep之前被interrupt 则 sleep方法抛出异常,再. -
java-有什么好的示例程序演示Thread.sleep()抛出的InterruptedException处理不当?
2019-11-04 00:15:24我一直在阅读有关InterruptedException的内容,并且很明显,没有在所有情况下都能正确处理...我想将其限制为演示Thread.sleep()的正确使用. 您将如何为此设计一个比较实际的示例程序? 到目前为止,这是我的想法: &... -
Java Thread.sleep的InterruptedException 线程阻塞 线程中断
2019-04-01 19:55:551.1.1 Thread.sleep抛异常 当某线程A处于Sleep状态时,另一个线程B调用了B.interrupt()方法,打断了A的Sleep过程,则A的Sleep会抛出异常。使用Catch后,线程不会等待Sleep时间,而是会立即执行。 下面的例子中,线程... -
Java Thread.sleep的InterruptedException
2017-10-26 10:16:111.1.1 Thread.sleep抛异常 当某线程A处于Sleep状态时,另一个线程B调用了B.interrupt()方法,打断了A的Sleep过程,则A的Sleep会抛出异常。使用Catch后,线程不会等待Sleep时间,而是会立即执行。 下面的例子... -
Thread.sleep()概述
2021-01-17 00:31:49Thread.sleep()被用来暂停当前线程的执行,会通知线程调度器把当前线程在指定的时间周期内置为wait状态。当wait时间结束,线程状态重新变为Runnable并等待CPU的再次调度执行。所以线程sleep的实际时间取决于线程调度... -
为什么kotlin调用Thread.sleep方法不需要捕获异常
2021-03-08 17:14:43今天用kotlin复习java时发现Thread.sleep方法居然不用捕获InterruptedException异常 Java: try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } Kotlin: Thread.sleep(3000) ... -
Thread.sleep()和TimeUnit.SECONDS.sleep()的区别
2019-07-26 13:43:33首先给出结论:线程使用中的暂停,建议优先使用TimeUnit类中的sleep() TimeUnit是什么? TimeUnit是java.util.concurrent包下面的一个类,TimeUnit提供了可读性更好的线程暂停操作。 首先来看源码,原来是对... -
Java Thread之Sleep()使用方法总结
2018-11-12 17:19:45Thread.sleep()是Thread类的一个静态方法,使当前线程休眠,进入阻塞状态(暂停执行),如果线程在睡眠状态被中断,将会抛出IterruptedException中断异常。。主要方法如下: 【a】sleep(long millis) 线程睡眠 ... -
java – 为什么Thread.sleep使用不好
2021-02-13 01:40:44大多数问题都有自己的特定用例:Java – alternative to thread.sleepIs there any better or alternative way to skip/avoid using Thread.sleep(1000) in Java?我的问题是非常通用的用例.等待条件完成.做一些操作.... -
Thread.sleep(0)的作用
2021-03-18 17:18:20Thread.sleep(0)的作用 Thread.Sleep(0)作用,就是“触发操作系统立刻重新进行一次CPU竞争”。竞争的结果也许是当前线程仍然获得CPU控制权,也许会换成别的线程获得CPU控制权。这也是我们在大循环里面经常会写一句... -
Thread. sleep()是否会抛出checked exception?
2016-11-15 22:46:39Thread. sleep()是否会抛出checked exception? Thread.sleep() 和 Object.wait(),都可以抛出 InterruptedException。这个异常是不能忽略的,因为它是一个检查异常(checked exception) -
Java中的Thread.sleep()– Java线程睡眠
2020-07-09 19:34:52Java中的Thread.sleep (Thread.sleep in Java) Thread.sleep() method can be used to pause the execution of current thread for specified time in milliseconds. The argument value for milliseconds can’t be... -
使用TimeUnit类中的sleep代替Thread.sleep
2018-03-07 21:36:26TimeUnit是java.util.concurrent包下面的一个类,TimeUnit提供了可读性更好的线程暂停操作,通常用来替换Thread.sleep(),在很长一段时间里Thread的sleep()方法作为暂停线程的标准方式,几乎所有Java程序员都熟悉它... -
【java】Thread.sleep(1000)/类作为参数/setter/getter方法的作用/匿名对象
2020-07-27 13:32:40表示当前代码休眠一秒,抛出异常 eg: /* * 一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。 * 把 main 方法的地址传递到这里 */ public void fixCar(Car car) throws ... -
java – Thread.sleep()在while循环中
2021-02-12 20:17:35我注意到NetBeans在我的Java代码中的while循环中警告我关于使用Thread.sleep(),所以我已经对此进行了一些研究。看起来,主要的问题是性能之一,当您的同步状态可能会在计数器仍然处于睡眠状态时成为现实,从而在... -
SystemClock.sleep()方法与Thread.sleep()方法的区别
2017-04-07 16:40:17最近在学习一个项目代码的过程中发现了一个许多延时的地方使用了sleep()方法,不禁感到奇怪,之前因为Thread.sleep()方法导致假死崩溃的情况让我吸取了教训,前辈是不会犯这种小错误的,心想难道SystemClock.sleep()... -
Thread.sleep()和Object.wait()的区别
2019-08-21 11:44:001、wait()方法来自于Object类,而sleep()方法来自于Thread类 //wait public final void wait() throws InterruptedException //sleep public static native void sleep(long millis) throws InterruptedException; ... -
JAVA中Thread.sleep(1000);提示有错误,但是加上try........catch就不报错了,什么原因,作用是什么?
2021-02-26 17:02:44当程序运行过程中发生错误时,就会“ 抛出异常',抛出异常比终止程序要灵活得多,这是因为可以提供一个“ 捕获” 异常的处理器 (handler) 对异常情况进行处理。如果没有提供处理器,程序就会终止,并在控制台上打印... -
Thread.sleep()与Thread.yield()的区别与联系
2017-07-20 21:50:01在JAVA并发程序的开发中,经常会用到这两个方法对程序进行测试,它们的相同点在于: 1. 都会暂缓执行当前线程; 2. 如果已经持有锁,那么在等待过程中都不会...2. Thread.sleep()会抛出中断异常,且能被中断,而Thr -
通过Thread.Sleep暂停执行
2018-04-28 10:59:28Thread.sleep导致当前线程在指定期间暂停执行。这是一种有效的方法,可以让应用程序的其他线程或其他可能运行在计算机系统上的应用程序可以得到处理器的时间片。sleep方法也可以用来操作程序的延时执行(如下面的...