An explicit attempt to race?

Many examples of using Java resources are as follows:

Resource r = openResource(); try { // use resource } finally { r.close(); } 

The r declaration must be outside of try -clause, which should be visible in finally -clause, but it also makes it look like a potential race condition: what if there is an interruption of the stream to the right between openResource() -call and try -clause input?

Could this mean that the resource does not actually close in this scenario?

Or does Java ensure that try-finally spans r "completely" despite syntax similar to it?

Or I need to write:

 Resource r = null; try { r = openResource(); // use resource } finally { if (r != null) r.close(); } 

to protect against thread interruptions?

+6
source share
4 answers

What if there is a thread interrupt right between the call to openResource () and the input of the try clause?

Then the thread will not raise InterruptedException until it hits any blocking call. This cannot happen before it gets into the try block, because there are no more blocking calls, assuming the method really returns. From the docs for InterruptedException :

Thrown when the thread is waiting, sleeping or otherwise busy, and the thread is interrupted before or during the action. Sometimes a method may want to check if the current thread has been interrupted, and if so, then throw this exception immediately.

Please note that even if you make a purchase inside the try block, this does not really prevent any race condition that would otherwise be - because you would rely on the method or constructor that comes back first. If an exception can occur after the method / constructor returns, why cannot it happen immediately before returning it, but after the resource has been received? If this happens, you cannot name anything close on ...

I would recommend using the try-with-resources statement in Java 7, but if you look at the JLS section 14.20.3.1 you will see that the extension looks like your first piece of code:

The value of the basic try-with-resources statement:

 try ({VariableModifier} R Identifier = Expression ...) Block 

defined by the following translation into the local variable declaration and the statement try-catch-finally:

 { final {VariableModifierNoFinal} R Identifier = Expression; Throwable #primaryExc = null; try ResourceSpecification_tail Block catch (Throwable #t) { ... #primaryExc = #t; throw #t; } finally { ... } } 
+3
source

Those examples of using Java resources can be written as an example that you specify where r initially set to null , but if they used Java 7 try-with-resources (Assuming Resource implements AutoCloseable ):

 try (Resource r = openResource()) { // use resource } 

Then they will be equivalent to the first example, where openResource() is called before the try block. The Java language specification for the try-with-resources defines semantics as equivalent to assigning a variable with an initializer before the block, and then entering into try-catch-finally .

There is a problem with the exception that occurred before the try block was entered. The problem is mostly theoretical. If openResource() returns normally, and there are no intermediate statements between assigning r and the start of the try block, it is unlikely, although not impossible, that some other thread will gain control before the try block begins, but even when your thread started again, it will enter the try block without incident. If another thread did something that caused the JVM to shut down, such as calling System.exit , you usually don't need to worry about closing resources. And even this case is unlikely.

If, on the other hand, there was a problem opening the resource, presumably openResource() will openResource() , which will prevent the assignment of r .

+4
source

There is no potential race condition. You either get an exception while calling getResource, or it can return zero, but there is no race condition. If your thread has been interrupted, you may get an InterruptedException, but this will prevent you from entering the try block.

+3
source

Source: https://habr.com/ru/post/973661/


All Articles