< 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 >