将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,调用者也无法知道除了
答案 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进行更权威的讨论。