为什么阻塞库方法经常通过调用静态interrupted()而不是实例方法isInterrupted)来响应中断



将java.util.concurrent.locks.AbstractQueuedSynchronizer中的以下代码视为标题中提出的想法的众多示例之一:

1258    public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws Interrupted Exception {
1259        if (Thread.interrupted())
1260            throw new InterruptedException();
1261        return tryAcquireShared(arg) >= 0 ||
1262            doAcquireSharedNanos(arg, nanosTimeout);
1263    }

为什么大多数阻塞库方法通过调用静态方法Thread.interrupted()而不是实例方法isInterrupted()来响应中断。调用静态方法也会清除中断状态,因此即使任务处理代码也会吞下中断异常,调用方也无法了解之外的中断状态

如果捕获InterruptedException,则中断的标志已被清除。异常本身就是此时的信号机制。捕捉器需要重新启用标志,或者直接注意线程移动到关闭位置。

基本上,您似乎认为API/行为契约应该有所不同,并且您想知道为什么"他们"以这种方式设计它,而不是您喜欢的方式。

我们无法回答这个问题。当讨论这些问题并做出决定时,这里没有人"在房间里"。如果你想要一个明确的答案,你需要找到最初的设计师并询问他们。

无论如何,这个问题是没有意义的。。。除非您正在计划设计和实现自己的编程语言。

标题中问题的答案是"因为实现CCD_ 4不直接公开CCD_;。显然,通过Thread.currentThread().isInterrupted()访问标志而不影响它很简单,但这不是重点。关键是使用Thread.interrupted()会更容易,因为这是你最应该做的

您对使用Thread.interrupted的代码的投诉

如果你正在检查你的线程是否被中断,你应该在代码中的某个点上,你可以对它做点什么,否则有什么意义?故意定义的机制阻止您悄悄退出循环。它特别鼓励您处理中断,故意鼓励您通过抛出中断来处理中断。

可疑的是调用isInterrupted的代码,而不是调用interrupted的代码。您应该而不是考虑安静地处理中断,您应该戏剧性地处理它,或者根本不处理它。是Thread.currentThread.isInterrupted()调用方悄悄地吸收了异常,从而导致了问题,而不是Thread.interrupted()的调用方。

请参阅Heinz M.Kabutz博士关于干净地关闭线程的文章,以获得更权威的讨论。

最新更新