InterruptedException
不知大家在写某些功能,需要线程睡一段时间的时候,有没有注意到,为什么要有一个下图这样的 try catch
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
在什么情况下会发产生这个异常呢?
下面是源代码中对他的描述
/**
* 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. The following code can be used to achieve
* this effect:
* <pre>
* if (Thread.interrupted()) // Clears interrupted status!
* throw new InterruptedException();
* </pre>
*/
public class InterruptedException extends Exception
总结来说,就是当一个线程在wait、sleep、或者其他阻塞状态的情况下,并且当线程被置为interruped状态时,会抛出该异常。
为什么要抛出有这个异常存在呢?它的作用是什么?
因为目前Java没有提供一种安全直接的方法来直接停止某个线程!!!没有任何java语言方面的需求要求一个被中断的程序应该终止。中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断
为了解决这个问题,java给出了这样一个设计方案,提供了一种中断策略:
1.提供一种标记方式,用来标记是否需要中断。
2.提供一种检测标记状态方式,检测该标记
3.对于简单的阻塞状态(可响应中断),通过抛出InterruptedException异常的方式,
4.对于复杂的阻塞状态(不可响应中断),通过上层主动在代码中判断该标记的状态,去决定各种自定义的处理方式。
将这套策略应对应到Thread中
方法 | 描述 |
---|---|
public void interrupt() | 标记方式:中断线程,将中断状态标记true |
public boolean isInterrupted() | 检测标记状态方式:并且检测后会重置状态为false |
wait()、join()、sleep() | 简单的阻塞状态(可响应中断) |
用户在线程中手动调用isInterrupted()判断 | 复杂的阻塞状态(不可响应中断) |
标准处理流程
所以,一个标准的InterruptedException处理方式类似如下代码
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
//简单的阻塞状态,当其他地方调用到该线程的 interrupt()方法,时,该线程如果执行在这个过程内,会抛出该异常
//用户自定义的收尾工作
}
if (Thread.currentThread().isInterrupted()) {
//复杂的阻塞状态
//用户手动判断是否需要收尾
}
}
Tips:
像Thread.suspend, Thread.stop这些方式,也是因为由于没有使用可中断机制而被Deprecated。