< prev index next >

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

Print this page

        

@@ -1,7 +1,5 @@
-package jdk.internal.ref;
-
 /*
  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it

@@ -23,158 +21,40 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 
+package jdk.internal.ref;
+
 import java.lang.ref.Cleaner;
-import java.lang.ref.Reference;
+import java.lang.ref.PhantomReference;
 import java.lang.ref.WeakReference;
 import java.util.Objects;
 
 /**
  * WeakCleanable 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 weakly reachable.
+ * When constructed, the object reference is registered with the {@link Cleaner}.
+ * The Cleaner invokes {@link #clean()} after the referent becomes weakly reachable
+ * if the WeakCleanable instance is still reachable at that time.
+ * Subclasses must ensure for WeakCleanable instance and its associated Cleaner
+ * to remain reachable if they want to ensure execution of the cleaning action.
  */
 public abstract class WeakCleanable<T> extends WeakReference<T>
         implements Cleaner.Cleanable {
 
     /**
-     * Links to previous and next in a doubly-linked list.
-     */
-    WeakCleanable<?> prev = this, next = this;
-
-    /**
-     * The list of WeakCleanable; synchronizes insert and remove.
-     */
-    private final WeakCleanable<?> list;
-
-    /**
-     * Constructs new {@code WeakCleanableReference} with
+     * Constructs new {@code WeakCleanable} 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 new reference with
-     */
-    public WeakCleanable(T referent, Cleaner cleaner) {
-        super(Objects.requireNonNull(referent), CleanerImpl.getCleanerImpl(cleaner).queue);
-        list = CleanerImpl.getCleanerImpl(cleaner).weakCleanableList;
-        insert();
-
-        // Ensure referent and cleaner remain accessible
-        Reference.reachabilityFence(referent);
-        Reference.reachabilityFence(cleaner);
-
-    }
-
-    /**
-     * Construct a new root of the list; not inserted.
-     */
-    WeakCleanable() {
-        super(null, null);
-        this.list = this;
-    }
-
-    /**
-     * Insert this WeakCleanableReference after the list head.
-     */
-    private void insert() {
-        synchronized (list) {
-            prev = list;
-            next = list.next;
-            next.prev = this;
-            list.next = this;
-        }
-    }
-
-    /**
-     * Remove this WeakCleanableReference 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 WeakCleanable reference and invoke {@link #performCleanup()},
-     * ensuring at-most-once semantics.
-     */
-    @Override
-    public final void clean() {
-        if (remove()) {
-            super.clear();
-            performCleanup();
-        }
-    }
-
-    /**
-     * Unregister this WeakCleanable 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
+     * @param cleaner  the {@code Cleaner} to register with
      */
-    @Override
-    public final boolean enqueue() {
-        throw new UnsupportedOperationException("enqueue");
+    protected WeakCleanable(T referent, Cleaner cleaner) {
+        super(Objects.requireNonNull(referent),
+              CleanerImpl.getCleanerImpl(cleaner).queue);
     }
 }
< prev index next >