InterruptedException异常

如果方法后面加了throws InterruptedException,则表明该方法中(或者该方法进一步调用的方法中)可能会抛出InterruptedException异常。

加了throws InterruptedException的方法

在Java的标准类库中,加了throws InterruptedException的典型方法有如下三个:

  • java.lang.Object类的wait方法
  • java.lang.Thread类的sleep方法
  • java.lang.Thread类的join方法

花费时间的方法

线程执行wait方法后,会进入等待队列,等待被notify/notifyAll。在等待期间,线程是不运行的,但需要花费时间来等待被notify/notifyAll。
线程执行sleep方法后,会暂停执行(暂停多长时间由参数指定)。这也是花费时间的方法。
线程执行join方法后,会等待指定线程终止。该方法需要花费时间,来等待指定线程终止。

可以取消的方法

花费时间的处理会降低程序的响应性,所以如果存在像下面这样可以中途停止执行(取消)的方法,就非常方便了。

  • 取消“wait方法等待notify/notifyAll”的处理
  • 取消“在sleep方法指定的时间内停止执行”的处理
  • 取消“join方法等待其他线程终止”的处理

sleep方法和interrupt方法

使用的interrupt方法是Thread类的实例方法。当执行interrupt时,线程并不需要获取Thread实例的锁。无论何时,任何线程都可以调用其他线程的interrupt方法。
interrupt方法被调用后,正在sleep的线程会终止暂停状态,抛出InterruptedException异常。
这样,线程的控制权就会转移到捕捉该异常的catch语句块中。

wait方法和interrupt方法

当使用interrupt方法时,该操作意即告诉正在wait的线程“不用再等待notify/notifyAll了,从等待队列出来吧”。
但在wait的情况下,需要注意锁的问题。线程在进入等待队列时,已经释放了锁。当正在wait的线程被调用interrupt方法时(即线程被取消执行时),该线程会在重新获取锁之后,抛出InterruptedException异常。在获取锁之前,线程不会抛出InterruptedException异常。

join方法和interrupt方法

由于调用join方法时无需获取锁,所以与使用sleep暂停运行时一样,线程的控制权也会立即跳到catch语句块中。

interrupt方法只是改变中断状态

所谓中断状态(interrupted status),是一种用于表示线程是否被中断的状态。
interrupt方法只是改变了线程的中断状态而已。
当线程A执行了sleep、wait、join而停止运行时,线程B调用了A的interrupt方法。这时,线程A的确会抛出InterruptedException异常。但这其实是因为sleep、wait、join方法内部对线程的中断状态进行了检查,进而抛出了InterruptedException异常。
如果没有调用sleep、wait、join等方法,或者没有编写检查线程的中断状态并抛出InterruptedException异常的代码,那么InterruptedException异常就不会被抛出。

F0oE24.png

isInterrupted方法——检查中断状态

isInterrupted是Thread类的实例方法,用于检查指定线程的中断状态。若指定线程处于中断状态,则返回true;若指定线程未处于中断状态(即处于非中断状态),则返回false。isInterrupted并不会改变中断状态。

Thread.interrupted方法——检查并清除中断状态

Thread.interrupted是Thread类的静态方法,用于检查并清除当前线程的中断状态。若当前线程处于中断状态,则返回true;若当前线程未处于中断状态,则返回false。调用Thread.interrupted后,中断状态会被清除(线程变为非中断状态)。
只有这个方法才可以清除中断状态。Thread.interrupted的操作对象是当前线程(即线程本身),所以该方法并不能用于清除其他线程的中断状态。