没有合适的资源?快使用搜索试试~ 我知道了~
首页Java处理InterruptedException异常的理论与实践
Java处理InterruptedException异常的理论与实践
2.1k 浏览量
更新于2023-05-21
评论
收藏 106KB PDF 举报
在使用Java的过程中,有个情景或许很多人见过,您在编写一个测试程序,程序需要暂停一段时间,于是调用 Thread.sleep()。但是编译器或 IDE 报错说没有处理检查到的 InterruptedException。InterruptedException 是什么呢,为什么必须处理它?下面跟着小编一起来看看。
资源详情
资源评论
资源推荐

Java处理处理InterruptedException异常的理论与实践异常的理论与实践
在使用Java的过程中,有个情景或许很多人见过,您在编写一个测试程序,程序需要暂停一段时间,于是调用
Thread.sleep()。但是编译器或 IDE 报错说没有处理检查到的 InterruptedException。InterruptedException 是什
么呢,为什么必须处理它?下面跟着小编一起来看看。
前言前言
对于 InterruptedException,一种常见的处理方式是 “生吞(swallow)” 它 —— 捕捉它,然后什么也不做(或者记录下它,不
过这也好不到哪去)—— 就像后面的 清单 4 一样。不幸的是,这种方法忽略了这样一个事实:这期间可能发生中断,而中断
可能导致应用程序丧失及时取消活动或关闭的能力。
阻塞方法阻塞方法
当一个方法抛出 InterruptedException 时,它不仅告诉您它可以抛出一个特定的检查异常,而且还告诉您其他一些事情。例
如,它告诉您它是一个阻塞(blocking)方法,如果您响应得当的话,它将尝试消除阻塞并尽早返回。
阻塞方法不同于一般的要运行较长时间的方法。一般方法的完成只取决于它所要做的事情,以及是否有足够多可用的计算资源
(CPU 周期和内存)。而阻塞方法的完成还取决于一些外部的事件,例如计时器到期,I/O 完成,或者另一个线程的动作(释
放一个锁,设置一个标志,或者将一个任务放在一个工作队列中)。一般方法在它们的工作做完后即可结束,而阻塞方法较难
于预测,因为它们取决于外部事件。阻塞方法可能影响响应能力,因为难于预测它们何时会结束。
阻塞方法可能因为等不到所等的事件而无法终止,因此令阻塞方法可取消 就非常有用(如果长时间运行的非阻塞方法是可取
消的,那么通常也非常有用)。可取消操作是指能从外部使之在正常完成之前终止的操作。由 Thread 提供并受
Thread.sleep() 和 Object.wait() 支持的中断机制就是一种取消机制;它允许一个线程请求另一个线程停止它正在做的事情。当
一个方法抛出 InterruptedException 时,它是在告诉您,如果执行该方法的线程被中断,它将尝试停止它正在做的事情而提前
返回,并通过抛出 InterruptedException 表明它提前返回。 行为良好的阻塞库方法应该能对中断作出响应并抛出
InterruptedException,以便能够用于可取消活动中,而不至于影响响应。
线程中断线程中断
每个线程都有一个与之相关联的 Boolean 属性,用于表示线程的中断状态(interrupted status)。中断状态初始时为 false;
当另一个线程通过调用 Thread.interrupt() 中断一个线程时,会出现以下两种情况之一。如果那个线程在执行一个低级可中断
阻塞方法,例如 Thread.sleep()、、 Thread.join() 或或 Object.wait(),,那么它将取消阻塞并抛出 InterruptedException。否则,
interrupt() 只是设置线程的中断状态。 在被中断线程中运行的代码以后可以轮询中断状态,看看它是否被请求停止正在做的事
情。中断状态可以通过 Thread.isInterrupted() 来读取,并且可以通过一个名为 Thread.interrupted() 的操作读取和清除。
中断是一种协作机制。当一个线程中断另一个线程时,被中断的线程不一定要立即停止正在做的事情。相反,中断是礼貌地请
求另一个线程在它愿意并且方便的时候停止它正在做的事情。有些方法,例如 Thread.sleep(),很认真地对待这样的请求,但
每个方法不是一定要对中断作出响应。对于中断请求,不阻塞但是仍然要花较长时间执行的方法可以轮询中断状态,并在被中
断的时候提前返回。 您可以随意忽略中断请求,但是这样做的话会影响响应。
中断的协作特性所带来的一个好处是,它为安全地构造可取消活动提供更大的灵活性。我们很少希望一个活动立即停止;如果
活动在正在进行更新的时候被取消,那么程序数据结构可能处于不一致状态。中断允许一个可取消活动来清理正在进行的工
作,恢复不变量,通知其他活动它要被取消,然后才终止。
处理处理 InterruptedException
如果抛出 InterruptedException 意味着一个方法是阻塞方法,那么调用一个阻塞方法则意味着您的方法也是一个阻塞方法,而
且您应该有某种策略来处理 InterruptedException。通常最容易的策略是自己抛出 InterruptedException,如清单 1 中
putTask() 和 getTask() 方法中的代码所示。 这样做可以使方法对中断作出响应,并且只需将 InterruptedException 添加到
throws 子句。
清单清单 1. 不捕捉不捕捉 InterruptedException,将它传播给调用者,将它传播给调用者
public class TaskQueue {
private static final int MAX_TASKS = 1000;
private BlockingQueue<Task> queue
= new LinkedBlockingQueue<Task>(MAX_TASKS);
public void putTask(Task r) throws InterruptedException {
queue.put(r);
}
public Task getTask() throws InterruptedException {
return queue.take();
}
}
有时候需要在传播异常之前进行一些清理工作。在这种情况下,可以捕捉 InterruptedException,执行清理,然后抛出异常。



















安全验证
文档复制为VIP权益,开通VIP直接复制

评论0