--- old/src/share/classes/java/lang/ref/ReferenceQueue.java 2013-07-01 13:38:58.534626339 +0200 +++ new/src/share/classes/java/lang/ref/ReferenceQueue.java 2013-07-01 13:38:58.222626345 +0200 @@ -55,25 +55,29 @@ private long queueLength = 0; boolean enqueue(Reference r) { /* Called only by Reference class */ - synchronized (r) { - if (r.queue == ENQUEUED) return false; - synchronized (lock) { - r.queue = ENQUEUED; - r.next = (head == null) ? r : head; - head = r; - queueLength++; - if (r instanceof FinalReference) { - sun.misc.VM.addFinalRefCount(1); - } - lock.notifyAll(); - return true; + synchronized (lock) { + // Check that since getting the lock this reference hasn't already been + // enqueued (and even then removed) + ReferenceQueue queue = r.queue; + if ((queue == NULL) || (queue == ENQUEUED)) { + return false; } + assert queue == this; + r.queue = ENQUEUED; + r.next = (head == null) ? r : head; + head = r; + queueLength++; + if (r instanceof FinalReference) { + sun.misc.VM.addFinalRefCount(1); + } + lock.notifyAll(); + return true; } } private Reference reallyPoll() { /* Must hold lock */ - if (head != null) { - Reference r = head; + Reference r = head; + if (r != null) { head = (r.next == r) ? null : r.next; r.queue = NULL; r.next = r;