< prev index next >

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

Print this page

        

@@ -23,32 +23,50 @@
  * questions.
  */
 
 package jdk.internal.ref;
 
+import jdk.internal.misc.InnocuousThread;
+
 import java.lang.ref.Cleaner;
-import java.lang.ref.Cleaner.Cleanable;
 import java.lang.ref.ReferenceQueue;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Objects;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Function;
-
-import jdk.internal.misc.InnocuousThread;
 
 /**
- * CleanerImpl manages a set of object references and corresponding cleaning actions.
- * CleanerImpl provides the functionality of {@link java.lang.ref.Cleaner}.
+ * CleanerImpl is the implementation of {@link Cleaner}.
  */
-public final class CleanerImpl implements Runnable {
+public class CleanerImpl implements Cleaner {
+
+    final Task task;
+
+    public CleanerImpl(ThreadFactory threadFactory) {
+        task = new Task();
+        task.start(this, threadFactory);
+    }
+
+    @Override
+    public Cleanable register(Object obj, Runnable action) {
+        Objects.requireNonNull(obj, "obj");
+        Objects.requireNonNull(action, "action");
+        return new CleanerImpl.PhantomCleanableRef(obj, this, action);
+    }
+
+    // package-private access to Task's state
+    PhantomCleanable<?> phantomCleanableList() { return task.phantomCleanableList; }
+    WeakCleanable<?> weakCleanableList() { return task.weakCleanableList; }
+    SoftCleanable<?> softCleanableList() { return task.softCleanableList; }
+    ReferenceQueue<Object> queue() { return task.queue; }
 
     /**
-     * An object to access the CleanerImpl from a Cleaner; set by Cleaner init.
+     * CleanerImpl.Task manages a set of object references and corresponding
+     * cleaning actions and executes them after they are enqueued.
      */
-    private static Function<Cleaner, CleanerImpl> cleanerImplAccess = null;
-
+    private static final class Task implements Runnable {
     /**
      * Heads of a CleanableList for each reference type.
      */
     final PhantomCleanable<?> phantomCleanableList;
 

@@ -58,35 +76,13 @@
 
     // The ReferenceQueue of pending cleaning actions
     final ReferenceQueue<Object> queue;
 
     /**
-     * Called by Cleaner static initialization to provide the function
-     * to map from Cleaner to CleanerImpl.
-     * @param access a function to map from Cleaner to CleanerImpl
+         * Constructor for Task.
      */
-    public static void setCleanerImplAccess(Function<Cleaner, CleanerImpl> access) {
-        if (cleanerImplAccess == null) {
-            cleanerImplAccess = access;
-        } else {
-            throw new InternalError("cleanerImplAccess");
-        }
-    }
-
-    /**
-     * Called to get the CleanerImpl for a Cleaner.
-     * @param cleaner the cleaner
-     * @return the corresponding CleanerImpl
-     */
-    static CleanerImpl getCleanerImpl(Cleaner cleaner) {
-        return cleanerImplAccess.apply(cleaner);
-    }
-
-    /**
-     * Constructor for CleanerImpl.
-     */
-    public CleanerImpl() {
+        Task() {
         queue = new ReferenceQueue<>();
         phantomCleanableList = new PhantomCleanableRef();
         weakCleanableList = new WeakCleanableRef();
         softCleanableList = new SoftCleanableRef();
     }

@@ -96,12 +92,12 @@
      * Ensure this is the CleanerImpl for the Cleaner.
      * When started waits for Cleanables to be queued.
      * @param cleaner the cleaner
      * @param threadFactory the thread factory
      */
-    public void start(Cleaner cleaner, ThreadFactory threadFactory) {
-        if (getCleanerImpl(cleaner) != this) {
+        void start(CleanerImpl cleaner, ThreadFactory threadFactory) {
+            if (cleaner.task != this) {
             throw new AssertionError("wrong cleaner");
         }
         // schedule a nop cleaning action for the cleaner, so the associated thread
         // will continue to run at least until the cleaner is reclaimable.
         new CleanerCleanable(cleaner);

@@ -153,10 +149,11 @@
                 // ignore exceptions from the cleanup action
                 // (including interruption of cleanup thread)
             }
         }
     }
+    }
 
     /**
      * Perform cleaning on an unreachable PhantomReference.
      */
     public static final class PhantomCleanableRef extends PhantomCleanable<Object> {
< prev index next >