1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.lang.ref; 27 28 import jdk.internal.ref.CleanerImpl; 29 30 import java.util.Objects; 31 import java.util.concurrent.ThreadFactory; 32 import java.util.function.Consumer; 33 import java.util.function.Function; 34 import java.util.function.LongConsumer; 35 import java.util.function.LongSupplier; 36 import java.util.function.Supplier; 37 38 /** 39 * {@code Cleaner} manages a set of object references and corresponding cleaning actions. 40 * <p> 41 * Cleaning actions are {@link #register(Object object, Runnable action) registered} 42 * to run after the cleaner is notified that the object has become 43 * phantom reachable. 44 * The cleaner uses {@link PhantomReference} and {@link ReferenceQueue} to be 45 * notified when the <a href="package-summary.html#reachability">reachability</a> 46 * changes. 47 * <p> 48 * Each cleaner operates independently, managing the pending cleaning actions 49 * and handling threading and termination when the cleaner is no longer in use. 50 * Registering an object reference and corresponding cleaning action returns 51 * a {@link Cleanable Cleanable}. The most efficient use is to explicitly invoke 52 * the {@link Cleanable#clean clean} method when the object is closed or 53 * no longer needed. 54 * The cleaning action is a {@link Runnable} to be invoked at most once when 55 * the object has become phantom reachable unless it has already been explicitly cleaned. 56 * Note that the cleaning action must not refer to the object being registered. 57 * If so, the object will not become phantom reachable and the cleaning action 58 * will not be invoked automatically. 59 * <p> 60 * The execution of the cleaning action is performed 61 * by a thread associated with the cleaner. 62 * All exceptions thrown by the cleaning action are ignored. 63 * The cleaner and other cleaning actions are not affected by 64 * exceptions in a cleaning action. 65 * The thread runs until all registered cleaning actions have 66 * completed and the cleaner itself is reclaimed by the garbage collector. 67 * <p> 68 * The behavior of cleaners during {@link System#exit(int) System.exit} 69 * is implementation specific. No guarantees are made relating 70 * to whether cleaning actions are invoked or not. 71 * <p> 72 * Unless otherwise noted, passing a {@code null} argument to a constructor or 73 * method in this class will cause a 74 * {@link java.lang.NullPointerException NullPointerException} to be thrown. 75 * 76 * @apiNote 77 * The cleaning action is invoked only after the associated object becomes 78 * phantom reachable, so it is important that the object implementing the 79 * cleaning action does not hold references to the object. 80 * In this example, a static class encapsulates the cleaning state and action. 81 * An "inner" class, anonymous or not, must not be used because it implicitly 82 * contains a reference to the outer instance, preventing it from becoming 83 * phantom reachable. 84 * The choice of a new cleaner or sharing an existing cleaner is determined 85 * by the use case. 86 * <p> 87 * If the CleaningExample is used in a try-finally block then the 88 * {@code close} method calls the cleaning action. 89 * If the {@code close} method is not called, the cleaning action is called 90 * by the Cleaner when the CleaningExample instance has become phantom reachable. 91 * <pre>{@code 92 * public class CleaningExample implements AutoCloseable { 93 * // A cleaner, preferably one shared within a library 94 * private static final Cleaner cleaner = <cleaner>; 95 * 96 * static class State implements Runnable { 97 * 98 * State(...) { 99 * // initialize State needed for cleaning action 100 * } 101 * 102 * public void run() { 103 * // cleanup action accessing State, executed at most once 104 * } 105 * } 106 * 107 * private final State; 108 * private final Cleaner.Cleanable cleanable 109 * 110 * public CleaningExample() { 111 * this.state = new State(...); 112 * this.cleanable = cleaner.register(this, state); 113 * } 114 * 115 * public void close() { 116 * cleanable.clean(); 117 * } 118 * } 119 * }</pre> 120 * The cleaning action could be a lambda but all too easily will capture 121 * the object reference, by referring to fields of the object being cleaned, 122 * preventing the object from becoming phantom reachable. 123 * Using a static nested class, as above, will avoid accidentally retaining the 124 * object reference. 125 * <p> 126 * <a id="compatible-cleaners"></a> 127 * Cleaning actions should be prepared to be invoked concurrently with 128 * other cleaning actions. 129 * Typically the cleaning actions should be very quick to execute 130 * and not block. If the cleaning action blocks, it may delay processing 131 * other cleaning actions registered to the same cleaner. 132 * All cleaning actions registered to a cleaner should be mutually compatible. 133 * @since 9 134 */ 135 public final class Cleaner { 136 137 /** 138 * The Cleaner implementation. 139 */ 140 final CleanerImpl impl; 141 142 static { 143 CleanerImpl.setCleanerImplAccess(new Function<Cleaner, CleanerImpl>() { 144 @Override 145 public CleanerImpl apply(Cleaner cleaner) { 146 return cleaner.impl; 147 } 148 }); 149 } 150 151 /** 152 * Construct a Cleaner implementation and start it. 153 */ 154 private Cleaner() { 155 impl = new CleanerImpl(); 156 } 157 158 /** 159 * Returns a new {@code Cleaner}. 160 * <p> 161 * The cleaner creates a {@link Thread#setDaemon(boolean) daemon thread} 162 * to process the phantom reachable objects and to invoke cleaning actions. 163 * The {@linkplain java.lang.Thread#getContextClassLoader context class loader} 164 * of the thread is set to the 165 * {@link ClassLoader#getSystemClassLoader() system class loader}. 166 * The thread has no permissions, enforced only if a 167 * {@link java.lang.System#setSecurityManager(SecurityManager) SecurityManager is set}. 168 * <p> 169 * The cleaner terminates when it is phantom reachable and all of the 170 * registered cleaning actions are complete. 171 * 172 * @return a new {@code Cleaner} 173 * 174 * @throws SecurityException if the current thread is not allowed to 175 * create or start the thread. 176 */ 177 public static Cleaner create() { 178 Cleaner cleaner = new Cleaner(); 179 cleaner.impl.start(cleaner, null); 180 return cleaner; 181 } 182 183 /** 184 * Returns a new {@code Cleaner} using a {@code Thread} from the {@code ThreadFactory}. 185 * <p> 186 * A thread from the thread factory's {@link ThreadFactory#newThread(Runnable) newThread} 187 * method is set to be a {@link Thread#setDaemon(boolean) daemon thread} 188 * and started to process phantom reachable objects and invoke cleaning actions. 189 * On each call the {@link ThreadFactory#newThread(Runnable) thread factory} 190 * must provide a Thread that is suitable for performing the cleaning actions. 191 * <p> 192 * The cleaner terminates when it is phantom reachable and all of the 193 * registered cleaning actions are complete. 194 * 195 * @param threadFactory a {@code ThreadFactory} to return a new {@code Thread} 196 * to process cleaning actions 197 * @return a new {@code Cleaner} 198 * 199 * @throws IllegalThreadStateException if the thread from the thread 200 * factory was {@link Thread.State#NEW not a new thread}. 201 * @throws SecurityException if the current thread is not allowed to 202 * create or start the thread. 203 */ 204 public static Cleaner create(ThreadFactory threadFactory) { 205 Objects.requireNonNull(threadFactory, "threadFactory"); 206 Cleaner cleaner = new Cleaner(); 207 cleaner.impl.start(cleaner, threadFactory); 208 return cleaner; 209 } 210 211 /** 212 * Registers an object and a cleaning action to run when the object 213 * becomes phantom reachable. 214 * Refer to the <a href="#compatible-cleaners">API Note</a> above for 215 * cautions about the behavior of cleaning actions. 216 * 217 * @param obj the object to monitor 218 * @param action a {@code Runnable} to invoke when the object becomes phantom reachable 219 * @return a {@code Cleanable} instance 220 */ 221 public Cleanable register(Object obj, Runnable action) { 222 Objects.requireNonNull(obj, "obj"); 223 Objects.requireNonNull(action, "action"); 224 return new CleanerImpl.PhantomCleanableRef(obj, this, action); 225 } 226 227 /** 228 * {@code Cleanable} represents an object and a 229 * cleaning action registered in a {@code Cleaner}. 230 * @since 9 231 */ 232 public interface Cleanable { 233 /** 234 * Unregisters the cleanable and invokes the cleaning action. 235 * The cleanable's cleaning action is invoked at most once 236 * regardless of the number of calls to {@code clean}. 237 */ 238 void clean(); 239 } 240 241 /** 242 * 1st registers an object then allocates a reference-valued resource by 243 * invoking resource allocator function and associates it with de-allocator 244 * function which will be called with the resource as cleaning action when 245 * the registered object becomes phantom reachable.<p> 246 * Using this method (when applicable) is preferable to using 247 * {@link #register(Object, Runnable)}, because it ensures correct 248 * order of actions - 1st register the object, then allocate the resource - 249 * which prevents resource leaks in rare circumstances when registration fails 250 * because of insufficient heap memory. The resource allocator function still 251 * bares all the responsibility for either returning normally with the 252 * allocated resource or throwing an unchecked exception in which case the 253 * resource should not be allocated or should already be de-allocated, because 254 * in such case, the de-allocator function is not called. 255 * Refer to the <a href="#compatible-cleaners">API Note</a> above for 256 * cautions about the behavior of cleaning actions. 257 * 258 * @param obj the object to monitor 259 * @param resourceAllocator the resource allocator function 260 * @param resourceDeallocator the resource de-allocator function, invoked as 261 * cleaning action with the allocated resource 262 * @param <T> the type of resource 263 * @return a {@link CleanableResource} instance holding the allocated resource 264 * with associated de-allocator function as cleaning action 265 * @since 10 266 */ 267 public <T> CleanableResource<T> createResource( 268 Object obj, 269 Supplier<? extends T> resourceAllocator, 270 Consumer<? super T> resourceDeallocator) 271 { 272 Objects.requireNonNull(obj, "obj"); 273 Objects.requireNonNull(resourceAllocator, "resourceConstructor"); 274 Objects.requireNonNull(resourceDeallocator, "resourceDestructor"); 275 return new CleanerImpl.PhantomCleanableResource<>(obj, this, resourceAllocator, resourceDeallocator); 276 } 277 278 /** 279 * {@code CleanableResource} represents an object holding some reference 280 * valued resource and a cleaning action for the resource registered in a 281 * {@code Cleaner}. 282 * 283 * @since 10 284 * 285 * @param <T> the type of allocated resource 286 */ 287 public interface CleanableResource<T> extends Cleanable { 288 /** 289 * Obtains the allocated resource. 290 * 291 * @return the allocated resource 292 * @throws IllegalStateException if the resource has already been 293 * {@link #clean() cleaned} 294 */ 295 T value(); 296 } 297 298 /** 299 * 1st registers an object then allocates a {@code long}-valued resource by 300 * invoking resource allocator function and associates it with de-allocator 301 * function which will be called with the resource as cleaning action when 302 * the registered object becomes phantom reachable.<p> 303 * Using this method (when applicable) is preferable to using 304 * {@link #register(Object, Runnable)}, because it ensures correct 305 * order of actions - 1st register the object, then allocate the resource - 306 * which prevents resource leaks in rare circumstances when registration fails 307 * because of insufficient heap memory. The resource allocator function still 308 * bares all the responsibility for either returning normally with the 309 * allocated resource or throwing an unchecked exception in which case the 310 * resource should not be allocated or should already be de-allocated, because 311 * in such case, the de-allocator function is not called. 312 * Refer to the <a href="#compatible-cleaners">API Note</a> above for 313 * cautions about the behavior of cleaning actions. 314 * 315 * @param obj the object to monitor 316 * @param resourceAllocator the resource allocator function 317 * @param resourceDeallocator the resource de-allocator function, invoked as 318 * cleaning action with the allocated resource 319 * @return a {@link LongCleanableResource} instance holding the allocated resource 320 * with associated de-allocator function as cleaning action 321 * @since 10 322 */ 323 public LongCleanableResource createLongResource( 324 Object obj, 325 LongSupplier resourceAllocator, 326 LongConsumer resourceDeallocator) 327 { 328 Objects.requireNonNull(obj, "obj"); 329 Objects.requireNonNull(resourceAllocator, "resourceConstructor"); 330 Objects.requireNonNull(resourceDeallocator, "resourceDestructor"); 331 return new CleanerImpl.PhantomLongCleanableResource(obj, this, resourceAllocator, resourceDeallocator); 332 } 333 334 /** 335 * {@code LongCleanableResource} represents an object holding some {@code long} 336 * valued resource and a cleaning action for the resource registered in a 337 * {@code Cleaner}. 338 * 339 * @since 10 340 */ 341 public interface LongCleanableResource extends Cleanable { 342 /** 343 * Obtains the allocated resource. 344 * 345 * @return the allocated resource 346 * @throws IllegalStateException if the resource has already been 347 * {@link #clean() cleaned} 348 */ 349 long value(); 350 } 351 }