目录
问题
知道为啥每次调用 Thread.sleep(...)
方法时,都要求你捕获 InterruptedException
异常吗?
try {
Thread.sleep(1000);//在捕获前sleep下会有红色波浪线
} catch (InterruptedException e) {
e.printStackTrace();
}
那sleep方法和 interrupt方法的关系又是什么呢?
sleep 和 interrupt
这里就要涉及到 java.lang.Thread API中的 interrupt()
方法和 isInterrupted()
方法了
void interrupt()
: 向线程发送中断请求。线程的中断状态将被设置为true。如果当前该线程被一个sleep方法调用阻塞,则抛出一个InterruptedException
异常。
static boolean interrupted()
:检测当前线程(即正在执行这个指令的线程)是否被中断。注意,这是一个静态方法。这个调用有一个副作用---它会将当前线程的中断状态重置为false。
boolean isInterrupted()
:检测一个线程是否被中断。与static interrupted()方法不同,这个调用不改变线程的中断状态。
不过以上对 interrupt 方法的解释还不够全面,一般来说应该有两种情况:
1、先sleep后interrupt:如果一个线程已经被 sleep 或 wait 调用阻塞了,这时再在该线程上调用 interrupt 方法,那么这个阻塞调用(即sleep或wait)将会被 InterruptedException 异常所中断;
2、先interrupt后sleep:如果一个线程已经设置了中断状态(即 isInterrupted()方法为 true ),这时再调用sleep方法,那么该线程将不会休眠,反而会被清除中断状态(false)并抛出 InterruptedException异常。
所以无论是哪种情况,都应当在每次调用 sleep 方法时,捕获 InterruptedException 异常。
补充
想写出更优美的代码,就不要在底层抑制 InterruptedException
异常,即在catch子句中什么也不做。不要这样做!如果想不出在catch子句中可以做什么有意义的工作,仍然有两个合理的选择:
1.在catch子句中调用 Thread.currentTread().interrupt() 来设置中断状态。这样一来调用者就可以检测中断状态。
...
try{
sleep(delay);
}catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
...
2.更好的选择是,直接在方法上用 throws InterruptedException
标记你的方法,并去掉try语句块。这样一来调用者(或者最终的run方法)就可以捕获这个异常。
void test() throws InterruptedException
{
...
sleep(delay);
...
}
参考文献:《Java核心技术》第12章 并发