< prev index next >

src/java.base/share/classes/jdk/internal/ref/SoftCleanable.java

Print this page

        

@@ -24,156 +24,36 @@
  */
 
 package jdk.internal.ref;
 
 import java.lang.ref.Cleaner;
-import java.lang.ref.Reference;
 import java.lang.ref.SoftReference;
 import java.util.Objects;
 
 /**
  * SoftCleanable subclasses efficiently encapsulate cleanup state and
- * the cleaning action.
- * Subclasses implement the abstract {@link #performCleanup()}  method
+ * the cleaning action. Subclasses implement the abstract {@link #clean()} method
  * to provide the cleaning action.
- * When constructed, the object reference and the {@link Cleaner.Cleanable Cleanable}
- * are registered with the {@link Cleaner}.
- * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the
- * referent becomes softly reachable.
+ * When constructed, the object reference is registered with the {@link Cleaner}.
+ * The Cleaner invokes {@link #clean()} after the referent becomes softly reachable
+ * if the SoftCleanable instance is still reachable at that time.
+ * Subclasses must ensure for SoftCleanable instance and its associated Cleaner
+ * to remain reachable if they want to ensure execution of the cleaning action.
  */
 public abstract class SoftCleanable<T> extends SoftReference<T>
         implements Cleaner.Cleanable {
 
     /**
-     * Links to previous and next in a doubly-linked list.
-     */
-    SoftCleanable<?> prev = this, next = this;
-
-    /**
-     * The list of SoftCleanable; synchronizes insert and remove.
-     */
-    private final SoftCleanable<?> list;
-
-    /**
-     * Constructs new {@code SoftCleanableReference} with
+     * Constructs new {@code SoftCleanable} with
      * {@code non-null referent} and {@code non-null cleaner}.
-     * The {@code cleaner} is not retained by this reference; it is only used
-     * to register the newly constructed {@link Cleaner.Cleanable Cleanable}.
+     * The {@code cleaner} is not retained; it is only used to
+     * register the newly constructed {@link Cleaner.Cleanable Cleanable} with
+     * its ReferenceQueue.
      *
      * @param referent the referent to track
      * @param cleaner  the {@code Cleaner} to register with
      */
-    public SoftCleanable(T referent, Cleaner cleaner) {
-        super(Objects.requireNonNull(referent), CleanerImpl.getCleanerImpl(cleaner).queue);
-        list = CleanerImpl.getCleanerImpl(cleaner).softCleanableList;
-        insert();
-
-        // Ensure referent and cleaner remain accessible
-        Reference.reachabilityFence(referent);
-        Reference.reachabilityFence(cleaner);
-    }
-
-    /**
-     * Construct a new root of the list; not inserted.
-     */
-    SoftCleanable() {
-        super(null, null);
-        this.list = this;
-    }
-
-    /**
-     * Insert this SoftCleanableReference after the list head.
-     */
-    private void insert() {
-        synchronized (list) {
-            prev = list;
-            next = list.next;
-            next.prev = this;
-            list.next = this;
-        }
-    }
-
-    /**
-     * Remove this SoftCleanableReference from the list.
-     *
-     * @return true if Cleanable was removed or false if not because
-     * it had already been removed before
-     */
-    private boolean remove() {
-        synchronized (list) {
-            if (next != this) {
-                next.prev = prev;
-                prev.next = next;
-                prev = this;
-                next = this;
-                return true;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Returns true if the list's next reference refers to itself.
-     *
-     * @return true if the list is empty
-     */
-    boolean isListEmpty() {
-        synchronized (list) {
-            return list == list.next;
-        }
-    }
-
-    /**
-     * Unregister this SoftCleanable reference and invoke {@link #performCleanup()},
-     * ensuring at-most-once semantics.
-     */
-    @Override
-    public final void clean() {
-        if (remove()) {
-            super.clear();
-            performCleanup();
-        }
-    }
-
-    /**
-     * Unregister this SoftCleanable and clear the reference.
-     * Due to inherent concurrency, {@link #performCleanup()} may still be invoked.
-     */
-    @Override
-    public void clear() {
-        if (remove()) {
-            super.clear();
-        }
-    }
-
-    /**
-     * The {@code performCleanup} abstract method is overridden
-     * to implement the cleaning logic.
-     * The {@code performCleanup} method should not be called except
-     * by the {@link #clean} method which ensures at most once semantics.
-     */
-    protected abstract void performCleanup();
-
-    /**
-     * This method always throws {@link UnsupportedOperationException}.
-     * Enqueuing details of {@link Cleaner.Cleanable}
-     * are a private implementation detail.
-     *
-     * @throws UnsupportedOperationException always
-     */
-    @Override
-    public final boolean isEnqueued() {
-        throw new UnsupportedOperationException("isEnqueued");
-    }
-
-    /**
-     * This method always throws {@link UnsupportedOperationException}.
-     * Enqueuing details of {@link Cleaner.Cleanable}
-     * are a private implementation detail.
-     *
-     * @throws UnsupportedOperationException always
-     */
-    @Override
-    public final boolean enqueue() {
-        throw new UnsupportedOperationException("enqueue");
+    protected SoftCleanable(T referent, Cleaner cleaner) {
+        super(Objects.requireNonNull(referent),
+              CleanerImpl.getCleanerImpl(cleaner).queue);
     }
 }
< prev index next >