简体   繁体   中英

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

I know that some Thread methods clear the interrupted flag (eg sleep, wait, ...). 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. 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:

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.

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. If the InterruptedException is in-flight the value of the flag is irrelevant. 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:

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:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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