线程sleep方法和InterruptedException异常

目录

        问题

        sleep 和 interrupt

        补充


问题

知道为啥每次调用  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章 并发

你可能感兴趣的:(Java核心技术,java,开发语言)