0

将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 ,调用者也无法了解中断状态,除了

4

3 回答 3

5

InterruptedException如果您捕获到,则中断标志已被清除,这始终是正确的。异常本身就是您此时的信号机制。捕手要么重新启用标志,要么直接注意线程移动到关闭。

于 2012-07-16T09:09:55.250 回答
1

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

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

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

于 2012-07-16T09:50:39.453 回答
1

标题中问题的答案是“因为实施RunnableisInterrupted()直接暴露”。显然,在不影响它的情况下访问标志很简单,Thread.currentThread().isInterrupted()但这不是重点。关键是它更容易使用Thread.interrupted(),因为这是你应该做的。

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

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

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

有关更权威的讨论,请参阅 Heinz M. Kabutz 博士关于彻底关闭线程的文章。

于 2012-07-16T10:44:27.340 回答