【发布时间】:2014-07-18 18:32:52
【问题描述】:
我知道某些线程方法会清除中断标志(例如睡眠、等待……)。 但他们为什么这样做呢?这是什么原因?
【问题讨论】:
-
@Zoyd:这个问题没有完全解决为什么。
标签: java multithreading sleep
我知道某些线程方法会清除中断标志(例如睡眠、等待……)。 但他们为什么这样做呢?这是什么原因?
【问题讨论】:
标签: java multithreading sleep
这是将中断设计为不完全等同于取消的结果。 Oracle 的指导是仅将中断用于取消,但这种观点可能随着时间的推移而出现。无论如何,设计并不强制这样做。你可以设计一个任务来响应中断,然后回到它正在做的事情。
在 Java Concurrency in Practice, 7.1, page 138 中,它说:
API 或语言规范中没有任何内容将中断与任何特定的取消语义联系起来,但在实践中,将中断用于除取消之外的任何事情都是脆弱的,并且难以在大型应用程序中维持。
它的设计方式在任何给定时间都只有一件事,要么是被捕获的 InterruptedException 要么是中断标志,来告诉线程的状态是什么。如果 InterruptedException 正在进行中,则标志的值无关紧要。这个想法似乎是捕获异常的代码应该决定是否应该设置中断标志。
这样使用InterruptedException退出循环就很方便了:
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(5000);
// ... do stuff ...
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
这里线程停止循环,因为异常是在循环外捕获的,它只与周围的代码有关,是否设置了中断标志。但是,如果您在循环中捕获 InterruptedException,例如:
while (!Thread.currentThread().isInterrupted()) {
// ... do stuff ...
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
(很多代码都是这样做的,因为程序员已经在他们的脑海中敲过,他们甚至不应该考虑使用异常来进行流控制),那么你必须设置中断标志。
我认为意图是应用程序开发人员应该使用异常来逃避中断的上下文,在靠近源头的地方吃异常并不能干净地工作。
【讨论】:
简而言之,因为这些方法将线程发送到“新”等待状态(在它被中断后回到运行状态)。先前设置的“中断”标志不再适用,因为线程在进入新的等待状态后没有被中断。
【讨论】: