Thread.sleep 没有抛出 InterruptedException

Posted

技术标签:

【中文标题】Thread.sleep 没有抛出 InterruptedException【英文标题】:InterruptedException not being thrown by Thread.sleep 【发布时间】:2020-09-27 00:13:37 【问题描述】:

我有一个线程休眠了一段时间并连续做一些工作。

public void run() 
    while(true) 
        try 
            Thread.sleep(SOME_RANDOM_TIME);
         catch (InterruptedException e) 
            return;
        
        doSomeLabour();
    

我有一堆这样的线程在Executors 上运行。当我在执行程序上调用shutdownNow 时,线程有时不会被终止。 shutdownNow 所做的只是在所有正在运行的线程上调用 interrupt 并且不接受任何新线程。

所以,基本上,我只是中断所有线程。

我明白,当 thread 不处于睡眠状态并被中断时,我的代码不会发生任何事情;但是,下次当线程在完成工作后尝试休眠时,sleep(..) 是否应该抛出 InterruptedException,因为该线程上仍然设置了中断标志?

【问题讨论】:

请提供minimal reproducible example。 【参考方案1】:

怎么样

while(!Thread.currentThread().isInterrupted()) 
    try 
        Thread.sleep(SOME_RANDOM_TIME);
     catch (InterruptedException e) 
        return;
    
    doSomeLabour();

改为?

Thread.interrupt() 的 JDK Javadoc 状态:

如果该线程在调用 wait()、wait(long) 时被阻塞, 或 Object 类或 join() 的 wait(long, int) 方法, join(long)、join(long, int)、sleep(long) 或 sleep(long, int)、方法 这个类,那么它的中断状态将被清除,它会 收到一个 InterruptedException。

所以 sleep() 本身不会抛出 InterruptedException,而是在线程当前处于睡眠状态时中断器会抛出。

【讨论】:

那行得通。但是,我试图了解 sleep 是如何引发 InterruptedException 的。 sleep 是否只有在线程在睡眠时被中断时才抛出 InterruptedException? 你的最后一句话没有意义。当然是 sleep 会抛出异常。 我想知道中断一个被阻塞的线程有什么意义?尝试中断已经阻塞的线程时是否会抛出此异常? @MarquisofLorne,很抱歉没有清楚地描述。 Sleep() 方法不抛出/管理 InterruptedException,即。这不是 sleep() 方法,它会不断检查“中断”标志。相反,如果线程被阻塞(例如,通过睡眠),则中断()调用会抛出 InterruptedException。相关部分:如果interrupt()遇到非阻塞线程,则不会出现InterruptedException,即使该线程稍后选择sleep()。 @KarthikChennenupati,我正在查看 JDK 源代码,例如。在hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/…,并阅读 Thread 类的 javadoc。

以上是关于Thread.sleep 没有抛出 InterruptedException的主要内容,如果未能解决你的问题,请参考以下文章

Thread 类 PowerMockito 模拟 Thread.sleep 抛出中断异常的场景

java 多线程基础

Thread.sleep是啥意思?有啥作用

并发基础 Thread 类的sleep()yeild()join()

线程相关的sleep()yield()wait()join()方法介绍

为Thread.Sleep(TimeSpan)设置高值