< prev index next >
src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java
Print this page
*** 23,42 ****
* questions.
*/
package jdk.internal.ref;
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.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}.
*/
--- 23,46 ----
* 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.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
+ import java.util.function.Consumer;
import java.util.function.Function;
! import java.util.function.LongConsumer;
! import java.util.function.LongSupplier;
! import java.util.function.Supplier;
/**
* CleanerImpl manages a set of object references and corresponding cleaning actions.
* CleanerImpl provides the functionality of {@link java.lang.ref.Cleaner}.
*/
*** 187,196 ****
--- 191,365 ----
}
/**
* Prevent access to referent even when it is still alive.
*
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public Object get() {
+ throw new UnsupportedOperationException("get");
+ }
+
+ /**
+ * Direct clearing of the referent is not supported.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException("clear");
+ }
+ }
+
+ /**
+ * Reference-valued resource, automatically cleaned when
+ * the tracked referent becomes phantom-reachable.
+ *
+ * @param <T> the type of resource
+ * @since 10
+ */
+ public static final class PhantomCleanableResource<T>
+ extends PhantomCleanable<Object>
+ implements Cleaner.CleanableResource<T> {
+
+ private final T resource;
+ private Consumer<? super T> deallocator;
+
+ /**
+ * Constructor for a phantom cleanable resource.
+ * @param obj the object to monitor
+ * @param cleaner the cleaner
+ * @param allocator the resource allocator function
+ * @param deallocator the resource de-allocator function
+ */
+ public PhantomCleanableResource(Object obj, Cleaner cleaner,
+ Supplier<? extends T> allocator,
+ Consumer<? super T> deallocator) {
+ super(obj, cleaner);
+ try {
+ this.resource = allocator.get();
+ } catch (Throwable t) {
+ // effectively de-register this cleanable in case
+ // resource allocation fails
+ super.clear();
+ throw t;
+ }
+ this.deallocator = deallocator;
+ }
+
+
+ @Override
+ protected void performCleanup() {
+ Consumer<? super T> deallocator = this.deallocator;
+ // only when deallocator was assigned, we can be sure that
+ // allocator.get() returned successfully
+ if (deallocator != null) {
+ // mark that cleanup has been performed
+ this.deallocator = null;
+ deallocator.accept(resource);
+ }
+ }
+
+ /**
+ * Access to the allocated resource.
+ *
+ * @return the allocated resource
+ */
+ @Override
+ public T value() {
+ if (deallocator == null) {
+ throw new IllegalStateException("Already cleaned");
+ }
+ return resource;
+ }
+
+ /**
+ * Prevent access to referent even when it is still alive.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public Object get() {
+ throw new UnsupportedOperationException("get");
+ }
+
+ /**
+ * Direct clearing of the referent is not supported.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException("clear");
+ }
+ }
+
+ /**
+ * Long-valued resource, automatically cleaned when
+ * the tracked referent becomes phantom-reachable.
+ *
+ * @since 10
+ */
+ public static final class PhantomLongCleanableResource
+ extends PhantomCleanable<Object>
+ implements Cleaner.LongCleanableResource {
+
+ private final long resource;
+ private LongConsumer deallocator;
+
+ /**
+ * Constructor for a phantom cleanable resource.
+ * @param obj the object to monitor
+ * @param cleaner the cleaner
+ * @param allocator the resource allocator function
+ * @param deallocator the resource de-allocator function
+ */
+ public PhantomLongCleanableResource(Object obj, Cleaner cleaner,
+ LongSupplier allocator,
+ LongConsumer deallocator) {
+ super(obj, cleaner);
+ try {
+ this.resource = allocator.getAsLong();
+ } catch (Throwable t) {
+ // effectively de-register this cleanable in case
+ // resource allocation fails
+ super.clear();
+ throw t;
+ }
+ this.deallocator = deallocator;
+ }
+
+
+ @Override
+ protected void performCleanup() {
+ LongConsumer deallocator = this.deallocator;
+ // only when deallocator was assigned, we can be sure that
+ // allocator.get() returned successfully
+ if (deallocator != null) {
+ // mark that cleanup has been performed
+ this.deallocator = null;
+ deallocator.accept(resource);
+ }
+ }
+
+ /**
+ * Access to the allocated resource.
+ *
+ * @return the allocated resource
+ */
+ @Override
+ public long value() {
+ if (deallocator == null) {
+ throw new IllegalStateException("Already cleaned");
+ }
+ return resource;
+ }
+
+ /**
+ * Prevent access to referent even when it is still alive.
+ *
* @throws UnsupportedOperationException always
*/
@Override
public Object get() {
throw new UnsupportedOperationException("get");
< prev index next >