简体   繁体   English

为什么Thread.sleep()清除中断的标志?

[英]WHY does Thread.sleep() clear the interrupted flag?

I know that some Thread methods clear the interrupted flag (eg sleep, wait, ...). 我知道一些Thread方法清除了中断的标志(例如,睡眠,等待......)。 But why do they do this? 但为什么他们这样做? What is the reason for it? 它是什么原因?

That is a result of interruption being designed not to be totally synonymous with cancellation. 这是因为中断被设计为完全取消同义词。 The guidance from Oracle is to use interruption only for cancellation, but that view may have been arrived at over time. Oracle的指导是仅将中断用于取消,但该视图可能已经过时。 In any event the design doesn't force that. 无论如何,设计并没有强制这样做。 You can design a task to respond to interruption, then go back to what it was doing. 您可以设计一个任务来响应中断,然后回到它正在做的事情。

In Java Concurrency in Practice, 7.1, page 138, it says: 在Java Concurrency in Practice,7.1,第138页中,它说:

There is nothing in the API or language specification that ties interruption to any specific cancellation semantics, but in practice, using interruption for anything but cancellation is fragile and dfficult to sustain in larger applications. API或语言规范中没有任何内容将中断与任何特定的取消语义联系起来,但在实践中,除了取消之外,使用中断是非常脆弱的,并且在大型应用程序中可以维持。

The way it was designed there is exactly one thing at any given time, either the InterruptedException being caught or the interrupt flag, to tell what the status of the thread is. 它的设计方式在任何给定时间都有一件事,要么是被捕获的InterruptedException,要么是中断标志,以告诉线程的状态。 If the InterruptedException is in-flight the value of the flag is irrelevant. 如果InterruptedException正在进行中,则该标志的值无关紧要。 And the idea seems to have been that the code catching the exception should decide whether the interrupted flag should be set or not. 并且想法似乎是捕获异常的代码应该决定是否应该设置中断的标志。

This way it's convenient to use the InterruptedException to exit a loop: 这样,使用InterruptedException退出循环很方便:

try {
    while (!Thread.currentThread().isInterrupted()) {
        Thread.sleep(5000);
        // ... do stuff ...
    }
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
}

Here the thread stops looping since the exception is caught outside the loop, it only matters to any surrounding code whether the interrupt flag is set or not. 这里线程停止循环,因为异常被捕获到循环外部,只关系中断标志是否设置,这对任何周围的代码都很重要。 However, if you catch the InterruptedException within the loop, like: 但是,如果您在循环中捕获InterruptedException,例如:

while (!Thread.currentThread().isInterrupted()) {
    // ... do stuff ...
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

(and a lot of code does this, because programmers have had it pounded into their heads that they should never ever even think about using exceptions for flow control), then you have to set the interrupted flag. (而且很多代码都是这样做的,因为程序员已经把它们弄得脑子里,他们甚至不应该考虑使用流控制的异常),然后你必须设置中断的标志。

I think the intention is that the application developer should use the exception to escape the context of the interruption, eating the exception close to the source does not work as cleanly. 我认为目的是应用程序开发人员应该使用异常来逃避中断的上下文,吃掉接近源的异常并不干净。

In short, because those methods send the thread into a "fresh" waiting state (after it was interrupted back into a running state). 简而言之,因为这些方法将线程发送到“新鲜”等待状态(在它被中断回到运行状态之后)。 The previously set "interrupted" flag no longer applies, as the thread has not been interrupted since entering the new waiting state. 先前设置的“中断”标志不再适用,因为线程自进入新的等待状态后未被中断。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM