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