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

时间:2012-07-16 09:07:28

标签: java java.util.concurrent

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()来响应中断。调用静态方法也会清除中断状态,因此即使任务处理代码吞下InterruptionException,调用者也无法知道除了

之外的中断状态。

3 个答案:

答案 0 :(得分:5)

总是如果你抓住InterruptedException,中断的标志已被清除。异常本身就是您的信号机制。捕手需要重新启用标志或直接注意线程移动到关闭状态。

答案 1 :(得分:1)

基本上,您似乎认为API /行为合同应该是不同的,并且您想知道为什么“他们”按原样设计它,而不是您喜欢的方式。

我们无法回答这个问题。当问题得到辩论并作出决定时,这里没有人“在房间里”。如果您想要一个明确的答案,您需要找到原始设计师并询问他们。

这个问题无论如何......除非你计划设计和实现自己的编程语言。

答案 2 :(得分:1)

标题中问题的答案是“因为实施Runnable不直接公开isInterrupted()”。显然,通过Thread.currentThread().isInterrupted()访问标志而不影响它很简单,但这不是重点。重点是故意使用Thread.interrupted()更容易,因为这是你应该做的。

您对使用Thread.interrupted

的代码的投诉

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

调用isInterrupted的代码是可疑的,而不是调用interrupted的代码。您应该考虑安静地处理中断,您应该大幅度处理或根本不处理。 Thread.currentThread.isInterrupted()调用者正在悄悄地吸收异常并因此导致问题,而不是Thread.interrupted()的调用者。

请参阅Heinz M. Kabutz博士Shutting down threads cleanly进行更权威的讨论。