我应该在'抛出新的DistrutedIOException()'之前做'Thread.currentThread().interrupt()'吗?

2022-09-03 08:07:08

我实现并注意到此函数中可能发生一个。经过一番搜索,我发现捕获并重新抛出一个是很常见的,如下所示:MyInputStream.read()InterruptedExceptionInterruptedExceptionInterruptedIOException

    try {
        ...
    } catch (InterruptedException e) {
        //Thread.currentThread().interrupt(); // <=== ???
        throw new InterruptedIOException();
    }

但只有大约50%的代码示例这样做。好吧,人们一致认为,你可以用DisruptedException做的最糟糕的事情就是吞下它,但是我应该在抛出不同的异常之前重新中断当前线程吗?Thread.currentThread().interrupt()

优点:单个中断请求可能有多个“收件人”。

CONTRA:在清除中断状态之前,某些功能(如日志记录)可能无法正常工作,这可能会导致细微的错误。

CONTRA:我们收到两个关于中断请求的通知:线程的中断状态和异常。最初,只有一个通知:线程的中断状态为 true 或抛出,但不是两者。InterruptedException

优点:没有人真正针对可能引发的i / o异常测试代码,并且与其他i / o异常不同;子句可能会吞噬中断状态。InterruptedIOExceptioncatch(IOException)

PS看起来无论我做什么,这是一种非常特殊的问题,需要一个特殊的处理程序,都不会得到解决。InterruptedIOExceptionIOException

PPS(编辑)我不能让原始传播,因为不能抛出(它不抛出任何其他东西)。而且我无法预测将调用的上下文:一个实例可以传递给任何接受参数的Java或第三方库函数。InterruptedExceptionInputStream.read()InterruptedExceptionthrows IOExceptionMyInputStream.read()MyInputStreamInputStream

至于旧的错误,它看起来只是关闭了,没有修复;中断状态的真正想法是代码的行为会有所不同。


答案 1

...我应该在引发其他异常之前重新中断当前线程吗?

如果某个upstack要检查中断标志,那么是的。否则,这无关紧要。

CONTRA:在清除中断状态之前,某些功能(如日志记录)可能无法正常工作,这可能会导致细微的错误。

根据我对分析的阅读,您链接到的错误仅适用于Java 6及更早版本,并且仅适用于Solaris平台。您现在可以打折了。(除非你有一个客户有deeeep口袋,否则你不应该为Java 6或更早版本做重要的应用程序。

CONTRA:我们收到两个关于中断请求的通知:线程的中断状态和异常。

它们是质量上不同类型的通知...

PS看起来无论我做什么,中断IOException是一种非常特殊的IOException需要特殊处理程序的问题将无法解决。

实际上,更好的策略可能是在捕获中设置中断的标志...或者只是允许原始异常传播。InterruptedIOExceptionInterrupted


答案 2

由于以下原因:

  1. InterruptedException不得吞咽,

  2. 任何(特别是)都可能被吞噬,即由第三方代码消费IOExceptionInterruptedIOException

  3. IOException旨在通知 I/O 发生的事件,而不是线程状态的变化

  4. 一些我们无法控制的代码可能会在抛出或重新抛出之前设置或清除线程中断状态InterruptedIOException

我决定:

  1. 当前线程必须在抛出中断IOException之前重新中断。
  2. 代码处理不应假定线程中断状态的任何特定状态InterruptedIOException
  3. 必须记录此行为:

    @throws InterruptedIOException if the current thread is interrupted (the thread
            interrupted status is true when InterruptedIOException is thrown)
    @throws IOException if this stream is closed or another IOException occurs.
    
    Note that due to possible interference from 3rd-party code, handlers 
    of InterruptedIOException should not assume any particular state
    of the thread interrupted status when they are invoked.
    

推荐