In the Java6 JDK, file: src/share/classes/com/sun/jmx/remote/internal/ArrayNotificationBuffer.java void removeSharer(xxx) { sync(this) { empty = ...; // set empty=true } // UNLOCK 'this' - 1 if( empty ) // test empty - 2 dispose(); // call dispose } public void dispose() { synchronized(this) { // RELOCK 'this' - 3 ... } } So basically the order of events is: - 1 : UNLOCK 'this' - 2 : test empty - 3 : RELOCK 'this' If another thread invalidates the 'empty' flag while at step 2 ('this' is unlocked), e.g. by calling addSharer on the same ArrayNotificationBuffer then you end up calling 'dispose()' on a non-empty sharer. Our stress-mode -Xcomp JCK test runs trigger this crash fairly routinely.
|