--- old/src/java.base/share/classes/java/lang/ref/Cleaner.java 2017-10-31 23:27:34.856594904 +0100 +++ new/src/java.base/share/classes/java/lang/ref/Cleaner.java 2017-10-31 23:27:34.711597374 +0100 @@ -29,7 +29,11 @@ import java.util.Objects; import java.util.concurrent.ThreadFactory; +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; /** * {@code Cleaner} manages a set of object references and corresponding cleaning actions. @@ -234,4 +238,114 @@ void clean(); } + /** + * 1st registers an object then allocates a reference-valued resource by + * invoking resource allocator function and associates it with de-allocator + * function which will be called with the resource as cleaning action when + * the registered object becomes phantom reachable.

+ * Using this method (when applicable) is preferable to using + * {@link #register(Object, Runnable)}, because it ensures correct + * order of actions - 1st register the object, then allocate the resource - + * which prevents resource leaks in rare circumstances when registration fails + * because of insufficient heap memory. The resource allocator function still + * bares all the responsibility for either returning normally with the + * allocated resource or throwing an unchecked exception in which case the + * resource should not be allocated or should already be de-allocated, because + * in such case, the de-allocator function is not called. + * Refer to the API Note above for + * cautions about the behavior of cleaning actions. + * + * @param obj the object to monitor + * @param resourceAllocator the resource allocator function + * @param resourceDeallocator the resource de-allocator function, invoked as + * cleaning action with the allocated resource + * @param the type of resource + * @return a {@link CleanableResource} instance holding the allocated resource + * with associated de-allocator function as cleaning action + * @since 10 + */ + public CleanableResource createResource( + Object obj, + Supplier resourceAllocator, + Consumer resourceDeallocator) + { + Objects.requireNonNull(obj, "obj"); + Objects.requireNonNull(resourceAllocator, "resourceConstructor"); + Objects.requireNonNull(resourceDeallocator, "resourceDestructor"); + return new CleanerImpl.PhantomCleanableResource<>(obj, this, resourceAllocator, resourceDeallocator); + } + + /** + * {@code CleanableResource} represents an object holding some reference + * valued resource and a cleaning action for the resource registered in a + * {@code Cleaner}. + * + * @since 10 + * + * @param the type of allocated resource + */ + public interface CleanableResource extends Cleanable { + /** + * Obtains the allocated resource. + * + * @return the allocated resource + * @throws IllegalStateException if the resource has already been + * {@link #clean() cleaned} + */ + T value(); + } + + /** + * 1st registers an object then allocates a {@code long}-valued resource by + * invoking resource allocator function and associates it with de-allocator + * function which will be called with the resource as cleaning action when + * the registered object becomes phantom reachable.

+ * Using this method (when applicable) is preferable to using + * {@link #register(Object, Runnable)}, because it ensures correct + * order of actions - 1st register the object, then allocate the resource - + * which prevents resource leaks in rare circumstances when registration fails + * because of insufficient heap memory. The resource allocator function still + * bares all the responsibility for either returning normally with the + * allocated resource or throwing an unchecked exception in which case the + * resource should not be allocated or should already be de-allocated, because + * in such case, the de-allocator function is not called. + * Refer to the API Note above for + * cautions about the behavior of cleaning actions. + * + * @param obj the object to monitor + * @param resourceAllocator the resource allocator function + * @param resourceDeallocator the resource de-allocator function, invoked as + * cleaning action with the allocated resource + * @return a {@link LongCleanableResource} instance holding the allocated resource + * with associated de-allocator function as cleaning action + * @since 10 + */ + public LongCleanableResource createLongResource( + Object obj, + LongSupplier resourceAllocator, + LongConsumer resourceDeallocator) + { + Objects.requireNonNull(obj, "obj"); + Objects.requireNonNull(resourceAllocator, "resourceConstructor"); + Objects.requireNonNull(resourceDeallocator, "resourceDestructor"); + return new CleanerImpl.PhantomLongCleanableResource(obj, this, resourceAllocator, resourceDeallocator); + } + + /** + * {@code LongCleanableResource} represents an object holding some {@code long} + * valued resource and a cleaning action for the resource registered in a + * {@code Cleaner}. + * + * @since 10 + */ + public interface LongCleanableResource extends Cleanable { + /** + * Obtains the allocated resource. + * + * @return the allocated resource + * @throws IllegalStateException if the resource has already been + * {@link #clean() cleaned} + */ + long value(); + } }