乐趣区

Java的Interrupt与线程中断

中断状态
每一个线程都有一个 boolean 属性,表示中断状态,初始值为 false。
中断线程:Thread.interrupt()
正常情况下,只是将线程的中断状态变为 true。线程中可以通过轮询中断状态,做出相应的处理。如果线程在阻塞状态下,线程将退出阻塞且中断状态将被清除(即为 false),且会抛出 InterruptException。(IO 操作忽略)
查询中断状态
(1)isInterrupted(),返回当前的中断状态,不会改变中断状态。(2)static interrupted(),返回当前中断状态,且会清除中断状态。(即第二次调用将返回 false)
处理 InterruptedException
(1)继续抛出。如果抛出 InterruptedException 意味着是一个阻塞方法,那么调用一个阻塞方法则意味着调用者也是一个阻塞方法,应该有某种策略来处理 InterruptedException。(2)捕获 InterruptedException,执行清理,再重新抛出 InterruptedException。(3)再次调用 interrupt()。当由 Runnable 定义的任务调用一个可中断的方法时,在这种情况下,不能重新抛出 InterruptedException,因为 Runnable 接口的 run 方法不允许抛出异常。当一个阻塞方法检测到中断并抛出 InterruptedException 但是不能重新抛出它,那么应该保留中断发生的证据,以便调用栈中更高层的代码能知道中断,并对中断做出响应,该任务可以通过调用 interrupt() 以重新中断当前线程来完成。
public void run() {
try {
while (true) {
Task task = queue.take(10, TimeUnit.SECONDS);
task.execute();
}
}
catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
}
中断一个不支持中断的类
如一个 IO 类会阻塞线程,但不支持中断。则可以写一个新 IO 类,继承 Thread 类,重写 interrupt 方法,在 interrupt 中关闭 IO,最后调用 super.interrupt();
待决中断
在进入阻塞前被中断,被称为待决中断。在调用阻塞方法时,会立刻抛出 InterruptException。
参考文章:多线程 -interrupt(),isInterrupted(),interrupted() – 小路不懂 2

退出移动版