如何处理BlockingQueue的InterruptedException?

6

我有一段类似于这样的代码,它在一个实现Runnable接口的类的run()方法中,并且多个该类的实例被启动。

do{
        try{
            String contractNum=contractNums.take();
           }catch(InterruptedException e){
            logger.error(e.getMessage(), e);
        }
  }while(!("*".equals(contractNum)));

contractNums是一个被多个线程共享的BlockingQueue<String>。有不同的Runnables将元素放入此队列。

当捕获到InterruptedException后,下一步应该做什么我并不确定,是否应该通过重新抛出RuntimeException(以便我的while循环终止),或者尝试再次从contractNum queue中取下一个元素并忽略InterruptedException

我不确定是否应将InterruptedException视为线程终止的致命条件或将其保持在while循环中。

请提供建议。

2个回答

4

7.1.2 中断策略

与任务应该有取消策略一样,线程也应该有中断策略。中断策略确定线程如何解释中断请求 - 当检测到请求时它会做什么(如果有的话),哪些工作单元被视为原子级别的工作单元,以及它对中断的反应速度。最明智的中断策略是线程级或服务级取消:尽快退出,必要时清理并可能通知一些拥有者实体线程正在退出。还可以建立其他中断策略,例如暂停或恢复服务,但具有非标准中断策略的线程或线程池可能需要限制为已经意识到策略的任务。

7.1.3 响应中断

如前所述,当您调用可中断阻塞方法(例如 Thread.sleep 或 BlockingQueue.put)时,有两种处理 InterruptedException 的实用策略:

• 传播异常(可能经过一些特定于任务的清理),使您的方法也成为可中断的阻塞方法;或

• 恢复中断状态,以便更高层次的调用堆栈代码可以处理它。

Java并发实践 第7章。

特别地,在您的代码中,您需要确保如果线程被中断,您的应用程序逻辑不会被打破。最好捕获您的中断异常。如何处理它取决于您,只需尽量确保不破坏应用程序逻辑即可。


2
感谢引用那本书。在第143-144页,描述了我的情况并建议我需要在线程即将完成时,在外部finally块中仅调用一次Thread.currentThread.interrupt() - 无论此异常被抛出的次数如何。在内部catch中,我应该忽略异常并重试从队列中take()元素。 - Sabir Khan

3

这要看情况。例如,在某些地方是否有意中断线程,告诉它完成任务(例如在关闭期间)?如果没有,那么您只需要处理可能会唤醒线程的虚假中断。如果您不希望处理受到影响,则可以忽略它们。它们绝对不是致命的异常,并且您不需要记录它们(特别是作为错误)。


不,没有任何有意的中断。谢谢。 - Sabir Khan
那么你就不需要对它们采取任何特别的行动了。 - Kayaman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接