jdk/src/share/classes/java/lang/ref/Reference.java
changeset 10895 7434064aba55
parent 5506 202f599c92aa
child 14342 8435a30053c1
--- a/jdk/src/share/classes/java/lang/ref/Reference.java	Mon Oct 31 16:23:43 2011 -0700
+++ b/jdk/src/share/classes/java/lang/ref/Reference.java	Mon Oct 31 17:38:15 2011 -0700
@@ -27,7 +27,6 @@
 
 import sun.misc.Cleaner;
 
-
 /**
  * Abstract base class for reference objects.  This class defines the
  * operations common to all reference objects.  Because reference objects are
@@ -69,7 +68,7 @@
      *     null.
      *
      *     Pending: queue = ReferenceQueue with which instance is registered;
-     *     next = Following instance in queue, or this if at end of list.
+     *     next = this
      *
      *     Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance
      *     in queue, or this if at end of list.
@@ -81,17 +80,28 @@
      * the next field is null then the instance is active; if it is non-null,
      * then the collector should treat the instance normally.
      *
-     * To ensure that concurrent collector can discover active Reference
+     * To ensure that a concurrent collector can discover active Reference
      * objects without interfering with application threads that may apply
      * the enqueue() method to those objects, collectors should link
-     * discovered objects through the discovered field.
+     * discovered objects through the discovered field. The discovered
+     * field is also used for linking Reference objects in the pending list.
      */
 
     private T referent;         /* Treated specially by GC */
 
     ReferenceQueue<? super T> queue;
 
+    /* When active:   NULL
+     *     pending:   this
+     *    Enqueued:   next reference in queue (or this if last)
+     *    Inactive:   this
+     */
     Reference next;
+
+    /* When active:   next element in a discovered reference list maintained by GC (or this if last)
+     *     pending:   next element in the pending list (or null if last)
+     *   otherwise:   NULL
+     */
     transient private Reference<T> discovered;  /* used by VM */
 
 
@@ -106,7 +116,8 @@
 
     /* List of References waiting to be enqueued.  The collector adds
      * References to this list, while the Reference-handler thread removes
-     * them.  This list is protected by the above lock object.
+     * them.  This list is protected by the above lock object. The
+     * list uses the discovered field to link its elements.
      */
     private static Reference pending = null;
 
@@ -120,14 +131,12 @@
 
         public void run() {
             for (;;) {
-
                 Reference r;
                 synchronized (lock) {
                     if (pending != null) {
                         r = pending;
-                        Reference rn = r.next;
-                        pending = (rn == r) ? null : rn;
-                        r.next = r;
+                        pending = r.discovered;
+                        r.discovered = null;
                     } else {
                         try {
                             lock.wait();
@@ -201,10 +210,8 @@
      *           been enqueued
      */
     public boolean isEnqueued() {
-        /* In terms of the internal states, this predicate actually tests
-           whether the instance is either Pending or Enqueued */
         synchronized (this) {
-            return (this.queue != ReferenceQueue.NULL) && (this.next != null);
+            return (this.next != null && this.queue == ReferenceQueue.ENQUEUED);
         }
     }