If I have a function with a try/finally section, and the thread running it is interrupted while in the try block, will the finally block execute before the interruption actually occurs?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
The effect of interruption is to throw an
InterruptedException
the next time a blocking operation occurs (in practice, the next time a method is called that specifies it can throw anInterruptedException
), at which point -- as usual -- the normaltry/catch
execution flow is followed, which does indeed execute thefinally
block after thetry
and any applicablecatch
es.In the comments to the answer, @Risadinha asked very valid question about whether code in
finally
block gets executed if we restore interruption flag insidecatch
block by callingThread.currentThread().interrupt()
.Here is small code snippet to test:
SomeContext class code:
Many of Oracle's Java tutorials are helpful (I have answers referencing the guarded blocks page and the SAX introduction), but they are not necessarily authoritative, and some of them have mistakes or are incomplete. The quote referenced in the question conflates interruption with the JVM exiting, which is confusing.
First, thread interruption in Java has nothing to do with OS-level interrupts. Sharing a name creates opportunities for confusion but there is no connection.
Next, JVM exit obviously kills the thread without an opportunity to do any cleanup. If the process dies before the thread has gotten as far as the finally block, too bad. But there's no comparison to interruption. Nothing about interruption prevents finally blocks from completing.
A design principle of interruption is that acting on the interruption requires the cooperation of the thread being interrupted. The thread interrupted responds at its discretion, the interruption doesn't compel the thread to do anything. All calling Thread#interrupt() does is set a flag on the thread. Blocking methods like wait or sleep check the flag to see if they should wake up early. (InterruptedException is a checked exception so you can tell who throws it when, and your Runnable can plan for it.) Also any code can use Thread#isInterrupted() to check whether its thread has had the flag set.
When Thread#sleep() recognizes the interrupted flag is set, it clears the flag before throwing InterruptedException. When your thread catches an InterruptedException it's good manners to restore the flag using Thread.currentThread().interrupt(), just in case there is any other code running in that thread that needs to know about the interruption. This comes into play when you have more complex situations with nested synchronizers where, for instance, some deeply nested component could get its sleep interrupted, letting it stay cleared could prevent higher layers from knowing about the interruption. In a simple toy example like the ones in other answers here, it doesn't matter if the flag is restored or not, nothing checks it again and the thread terminates.
A Thread Interrupt in Java is just setting a flag. It doesn't cause anything special to happen to currently executing code, or affect the flow of control.
If your thread is engaged in, or attempts to enter, an operation that throws InterruptedException, then the exception is thrown from the point where that method is invoked and if it's inside a try block, the finally will execute before the exception leaves just like normal.
It will execute the same way as with any other exception from the try block, not before the interruption.
According to the Java Tutorials, "if the thread executing the
try
orcatch
code is interrupted or killed, thefinally
block may not execute even though the application as a whole continues."Here's the full passage:
...
It prints - finally executed