Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I exit a monitor in bytecode properly?

I was reading the JVM specification to try to figure out how to properly handle monitors. The example they give in the relevant section looks like this:

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

I can not figure out why the second exception table entry is needed. If an exception is thrown by monitorexit do I really want to attempt to exit the monitor again? Possible exceptions thrown as far as I can tell are NullPointerException and IllegalMonitorStateException.

like image 551
user11171 Avatar asked Oct 04 '22 05:10

user11171


1 Answers

There is an Java Bug for this that has been closed as "Not an issue" - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4414101. (Kudos to Tom Anderson for finding it.)

The Evaluation section of the Bug is really enlightening.

It starts by talking about dealing with "asynchronous" exceptions; i.e. the ThreadDeath exception that is how the (deprecated!) Thread.stop() method is implemented. The mysterious handler ensures that the monitor lock is released even if the "thread stop" happens at the critical point where the JVM is trying to release the lock.

Then Neil Gafter adds that even the hypothetical infinite loop (as described in this Question) is correct behaviour according to the JLS. The JLS says that monitor will always be released before the thread continues. If it is impossible to do that, then putting the thread into an infinite loop is more correct than doing anything else.

like image 109
Stephen C Avatar answered Oct 07 '22 19:10

Stephen C