The code is not "calling" the monitorexit
instruction twice. It is executing it once on two different code paths.
- The first codepath is for when the code in the
synchronized
block exits normally.
- The second codepath is in an implicit exception handling path for the case where the block terminates abnormally.
You could write the bytecodes in the example as pseudo-code that looks like this:
void onlyMe(Foo f) {
monitorEntry(f);
try {
doSomething();
monitorExit();
} catch (Throwable any) {
monitorExit();
throw any;
}
}
If you want more information on this, take a look at this older question: