JDK-8014890 : (ref) Reference queues may return more entries than expected
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: hs25,8
  • Priority: P3
  • Status: Resolved
  • Resolution: Duplicate
  • OS: solaris
  • CPU: generic
  • Submitted: 2013-05-20
  • Updated: 2013-09-12
  • Resolved: 2013-07-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 Other
8Fixed hs25Resolved
Related Reports
Relates :  
Description
The following program fails because the reference queue returns more references than actually enqueued.

import java.lang.ref.*;

public class EnqueuePollRace {

    public static void main(String args[]) throws Exception {
        new WeakRef().run();
        System.out.println("Test passed.");
    }

    static class WeakRef {
        ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
        final int numReferences = 100;
        final Reference refs[] = new Reference[numReferences];
        final int iterations = 100;

        void run() throws InterruptedException {
            for (int i = 0; i < iterations; i++) {
                queue = new ReferenceQueue<Object>();

                for (int j = 0; j < refs.length; j++) {
                    refs[j] = new WeakReference(new Object(), queue);
                }

                System.gc(); // enqueues references into the list of discovered references

                // now manually enqueue all of them
                for (int j = 0; j < refs.length; j++) {
                    refs[j].enqueue();
                }
                // and get them back. There should be exactly numReferences
                // entries in the queue now.
                int foundReferences = 0;
                while (queue.poll() != null) {
                    foundReferences++;
                }

                if (foundReferences != refs.length) {
                    throw new RuntimeException("Got " + foundReferences + " references in the queue, but expected " + refs.length);
                }
            }
        }
    }
}

Comments
Duplicate of "backport" in JDK 8020452; this is due to assigning to core libs/jdk but not fixing the fix version
18-07-2013

I concur that there is a race in Reference.enqueue() call and ReferenceQueue.poll() call. I think ReferenceQueue.enqueue(Reference r) should check if r.queue == this before setting r.queue = ENQUEUED; otherwise, return false.
12-06-2013

I can't reproduce this on solaris-i586. Is this only on solaris-sparc?
11-06-2013

There is a race between the call to ReferenceQueue.enqueue() in the reference handler thread/the enqeue() call in the program, and the manual polling in ReferenceQueue::poll() I.e. relevant ReferenceHandler code: 1: ReferenceQueue q = r.queue; // r is the reference 2: if (r != ReferenceQueue.NULL) q.enqueue(). relevant ReferenceQueue::poll() code (I removed lots of code here) 1: synchronized(lock) { 2: r.queue = ReferenceQueue.NULL; 3:} relevant code So if the enqueue() and poll() calls in the example program occur between the evaluation of the if and the actual enqueuing in the reference handler code (line 2), the reference will be enqueued again. Although the code in poll() changed the value of r.queue to NULL, "q" in the reference handler still contains the original queue.
11-06-2013

Can reproduce, cause unkown - unsure if it is a bug too still. (On hs25b33 and 34, windows 32 bit, not on other platforms though that might be a coincidence)
10-06-2013

RULE api/java_lang/ref/ReferenceQueue/index_Poll TestCase [ReferenceQueue2014] only 101 out of 100 enqueued references are in the queue RULE api/java_lang/ref/ReferenceQueue/index_Poll TestCase [ReferenceQueue2016] only 101 out of 100 enqueued references are in the queue
04-06-2013

Dima please check if it is a compatibility issue. We need to raise priority and mark it correspondingly.
21-05-2013

We should check if this affects JDK 7. We should also check this on pre/post JDK8-b14 because of the fix for JDK-4243978
21-05-2013