Is it possible to simplify a synchronized block for a Try-finally block at the Bytecode level?

By writing my own compiler for a Java-like language, I had a compilation problem synchronized blocks. I came up with the following idea to simplify them into blocks try-finally:

synchonized (obj) {
     statements...
}

Can be replaced by

Object _lock = obj
_monitorEnter(lock)
try {
    statements...
}
finally {
    _monitorExit(lock)
}

Where _monitorEnterand _monitorExitrepresent the team MONITORENTERand MONITOREXIT.

Am I going to correct this assumption about how compiled synchronized, or am I missing something?

EDIT

return throw . , lock MONITOREXIT *RETURN throw. finally ?

+4
2

. synchronized Java monitorenter monitorexit. JVM .

Java , ( monitorexit) ( return).

-, , synchronized, try-finally .

finally . , , - , synchronized. , monitorexit. ( , ).

void onlyMe(Foo f) {
    synchronized(f) {
        doSomething();
    }
}

Method void onlyMe(Foo)
0   aload_1             // Push f
1   dup                 // Duplicate it on the stack
2   astore_2            // Store duplicate in local variable 2
3   monitorenter        // Enter the monitor associated with f
4   aload_0             // Holding the monitor, pass this and...
5   invokevirtual #5    // ...call Example.doSomething()V
8   aload_2             // Push local variable 2 (f)
9   monitorexit         // Exit the monitor associated with f
10  goto 18             // Complete the method normally
13  astore_3            // In case of any throw, end up here
14  aload_2             // Push local variable 2 (f)
15  monitorexit         // Be sure to exit the monitor!
16  aload_3             // Push thrown value...
17  athrow              // ...and rethrow value to the invoker
18  return              // Return in the normal case
Exception table:
From    To      Target      Type
4       10      13          any
13      16      13          any
+5

Java - try-finally, . , : , monitorexit, , . , Java.

0

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


All Articles