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

今天春*_*天春天 3 java multithreading sleep

我知道一些Thread方法清除了中断的标志(例如,睡眠,等待......).但为什么他们这样做?它是什么原因?

Nat*_*hes 6

这是因为中断被设计为完全取消同义词.Oracle的指导是仅将中断用于取消,但该视图可能已经过时.无论如何,设计并没有强制这样做.您可以设计一个任务来响应中断,然后回到它正在做的事情.

在Java Concurrency in Practice,7.1,第138页中,它说:

API或语言规范中没有任何内容将中断与任何特定的取消语义联系起来,但在实践中,使用中断除了取消之外的任何事情都是脆弱的,并且在较大的应用程序中需要维持.

它的设计方式在任何给定时间都有一件事,要么是被捕获的InterruptedException,要么是中断标志,以告诉线程的状态.如果InterruptedException正在进行中,则该标志的值无关紧要.并且想法似乎是捕获异常的代码应该决定是否应该设置中断的标志.

这样,使用InterruptedException退出循环很方便:

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

这里线程停止循环,因为异常被捕获到循环外部,只关系中断标志是否设置,这对任何周围的代码都很重要.但是,如果您在循环中捕获InterruptedException,例如:

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

(而且很多代码都是这样做的,因为程序员已经把它们弄得脑子里,他们甚至不应该考虑使用流控制的异常),然后你必须设置中断的标志.

我认为目的是应用程序开发人员应该使用异常来逃避中断的上下文,吃掉接近源的异常并不干净.