我应该在`throw new InterruptedIOException()`之前执行`Thread.currentThread().interrupt()`吗?

184*_*615 16 java multithreading android

我实现MyInputStream.read()并注意到InterruptedException这个函数可能会发生.经过一番搜索后,我发现抓住InterruptedException并重新抛出一个InterruptedIOException类似于:

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

但只有大约50%的代码样本Thread.currentThread().interrupt().好吧,同意你可以做的最糟糕的事情InterruptedException是吞下它,但是我应该在抛出一个不同的异常之前重新中断当前的线程吗?

PRO:单个中断请求可能有多个"收件人".

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

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

PRO:没有人真正针对可能抛出的异常异常测试代码,并且与InterruptedIOException其他i/o异常不同; 一个catch(IOException)条款可以吞下被中断的状态.

PS它看起来像我做的任何事情,InterruptedIOException一个非常特殊的IOException需要特殊处理程序的问题将无法解决.

PPS(编辑)我不能让原始InterruptedException传播,因为InputStream.read()不能抛出InterruptedException(它throws IOException并没有抛出任何其他东西).我无法预测MyInputStream.read()将被调用的上下文:MyInputStream可以将实例传递给任何带InputStream参数的Java或第三方库函数.

对于旧的bug,看起来它只是关闭,而不是固定; 并且中断状态的想法是代码的行为会有所不同.

muu*_*ued 2

我建议抛出ClosedByInterruptException。虽然它属于 NIO 库,但它比旧的InterruptedIOException具有更好定义的 API ,使其更易于处理。例如:

try {
    ...
} catch (InterruptedException e) {
    close(); // obeying API of ClosedByInterruptException
    Thread.currentThread().interrupt(); // again, obeying API
    throw new ClosedByInterruptException();
}
Run Code Online (Sandbox Code Playgroud)

另请参见Thread#interrupt()。如果您想重新抛出原始异常,您可以使用:

try {
    ...
} catch (InterruptedException e) {
    throw e;
}
Run Code Online (Sandbox Code Playgroud)

所以你保留堆栈跟踪。在这种情况下,中断状态保持清晰,正如InterruptedException的 API 所建议的那样。