We hit an extremely surprising exception today. Inside of a synchronized block, we call wait() and it throws IllegalMonitorStateException. What can cause this?
This is happening in well-tested open source code:
http://svn.apache.org/viewvc/river/jtsk/trunk/src/com/sun/jini/jeri/internal/mux/Mux.java?view=markup#l222
We eliminated the obvious causes:
- are we synchronized on the right variable? Yes, it’s
muxLock - is it a mutable variable? No,
muxLockis final - are we using any weird “-XX:” JVM flags that might affect monitor behavior? No, but we are launching the JVM embedded inside a C++ app via JNI.
- is this a strange JVM? No, it’s Sun’s 1.6.0_25 win/x64 JRE
- is this a known JVM bug? Can’t find anything relevant at http://bugs.sun.com/bugdatabase
So, I’m trying to think of more far-fetched explanations.
- could an uncaught out-of-memory error cause the monitor state to be screwed up? We’re looking at this, but we’re seeing no evidence of memory errors yet.
UPDATE: (based on comment)
I’ve also verified from the stacktrace and breakpoint that the thread is indeed inside the synchronized block when the exception is thrown. It’s not the case that some other unrelated code is emitting the exception (unless something is REALLY confusing Eclipse!)
The only suspicious thing I see that you are passing a reference to ‘this’ to some other object in your constructor. Is it possible (in fact, not unlikely) that, through weird re-ordering of things, if some other thread gets that reference to ‘this’ and calls the method that uses the muxlock, things can go extremely wrong.
The Java Language Specification is pretty specific about this:
In other words, if another thread gets hold of the ‘this’ reference before the constructor is finished, the final field ‘muxlock’ might not be correctly initialized yet. In general, publishing a reference to ‘this’ before the constructor has finished can be pretty dangerous, especially in threaded situations.
Some potentially useful discussion about such things:
http://madpropellerhead.com/random/20100328-java-final-fields-are-not-as-final-as-you-may-think
For some older, but still useful general discussion of why publishing ‘this’ in a constructor is a very bad idea in general, see for instance:
http://www.ibm.com/developerworks/java/library/j-jtp0618/index.html