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.Function; 33 34 // Android-changed: Use the shared SystemCleaner instance on Android. 35 // Android-changed: Exceptions are only ignored by Cleaner.create() threads. 36 /** 37 * {@code Cleaner} manages a set of object references and corresponding cleaning actions. 38 * <p> 39 * Cleaning actions are {@link #register(Object object, Runnable action) registered} 40 * to run after the cleaner is notified that the object has become 41 * phantom reachable. 42 * The cleaner uses {@link PhantomReference} and {@link ReferenceQueue} to be 43 * notified when the <a href="package-summary.html#reachability">reachability</a> 44 * changes. 45 * <p> 46 * Each cleaner operates independently, managing the pending cleaning actions 47 * and handling threading and termination when the cleaner is no longer in use. 48 * Registering an object reference and corresponding cleaning action returns 49 * a {@link Cleanable Cleanable}. The most efficient use is to explicitly invoke 50 * the {@link Cleanable#clean clean} method when the object is closed or 51 * no longer needed. 52 * The cleaning action is a {@link Runnable} to be invoked at most once when 53 * the object has become phantom reachable unless it has already been explicitly cleaned. 54 * Note that the cleaning action must not refer to the object being registered. 55 * If so, the object will not become phantom reachable and the cleaning action 56 * will not be invoked automatically. 57 * <p> 58 * The execution of the cleaning action is performed 59 * by a thread associated with the cleaner. 60 * The thread runs until all registered cleaning actions have 61 * completed and the cleaner itself is reclaimed by the garbage collector. 62 * <p> 63 * The behavior of cleaners during {@link System#exit(int) System.exit} 64 * is implementation specific. No guarantees are made relating 65 * to whether cleaning actions are invoked or not. 66 * <p> 67 * Unless otherwise noted, passing a {@code null} argument to a constructor or 68 * method in this class will cause a 69 * {@link java.lang.NullPointerException NullPointerException} to be thrown. 70 * 71 * @apiNote 72 * The cleaning action is invoked only after the associated object becomes 73 * phantom reachable, so it is important that the object implementing the 74 * cleaning action does not hold references to the object. 75 * In this example, a static class encapsulates the cleaning state and action. 76 * An "inner" class, anonymous or not, must not be used because it implicitly 77 * contains a reference to the outer instance, preventing it from becoming 78 * phantom reachable. 79 * The choice of a new cleaner or sharing an existing cleaner is determined 80 * by the use case. 81 * <p> 82 * If the CleaningExample is used in a try-finally block then the 83 * {@code close} method calls the cleaning action. 84 * If the {@code close} method is not called, the cleaning action is called 85 * by the Cleaner when the CleaningExample instance has become phantom reachable. 86 * <pre>{@code 87 * public class CleaningExample implements AutoCloseable { 88 * // Use the shared android.system.SystemCleaner instance on Android. 89 * private static final Cleaner cleaner = SystemCleaner.cleaner(); 90 * 91 * static class State implements Runnable { 92 * 93 * State(...) { 94 * // initialize State needed for cleaning action 95 * } 96 * 97 * public void run() { 98 * // cleanup action accessing State, executed at most once 99 * } 100 * } 101 * 102 * private final State; 103 * private final Cleaner.Cleanable cleanable 104 * 105 * public CleaningExample() { 106 * this.state = new State(...); 107 * this.cleanable = cleaner.register(this, state); 108 * } 109 * 110 * public void close() { 111 * cleanable.clean(); 112 * } 113 * } 114 * }</pre> 115 * The cleaning action could be a lambda but all too easily will capture 116 * the object reference, by referring to fields of the object being cleaned, 117 * preventing the object from becoming phantom reachable. 118 * Using a static nested class, as above, will avoid accidentally retaining the 119 * object reference. 120 * <p> 121 * <a id="compatible-cleaners"></a> 122 * Cleaning actions should be prepared to be invoked concurrently with 123 * other cleaning actions. 124 * Typically the cleaning actions should be very quick to execute 125 * and not block. If the cleaning action blocks, it may delay processing 126 * other cleaning actions registered to the same cleaner. 127 * All cleaning actions registered to a cleaner should be mutually compatible. 128 * @since 9 129 */ 130 public final class Cleaner { 131 132 /** 133 * The Cleaner implementation. 134 */ 135 final CleanerImpl impl; 136 137 static { CleanerImpl.setCleanerImplAccess(new Function<Cleaner, CleanerImpl>() { @Override public CleanerImpl apply(Cleaner cleaner) { return cleaner.impl; } })138 CleanerImpl.setCleanerImplAccess(new Function<Cleaner, CleanerImpl>() { 139 @Override 140 public CleanerImpl apply(Cleaner cleaner) { 141 return cleaner.impl; 142 } 143 }); 144 } 145 146 /** 147 * Construct a Cleaner implementation and start it. 148 */ Cleaner()149 private Cleaner() { 150 impl = new CleanerImpl(); 151 } 152 Cleaner(ReferenceQueue queue)153 private Cleaner(ReferenceQueue queue) { 154 impl = new CleanerImpl(queue); 155 } 156 157 /** 158 * Returns a new {@code Cleaner}. 159 * <p> 160 * The cleaner creates a {@link Thread#setDaemon(boolean) daemon thread} 161 * to process the phantom reachable objects and to invoke cleaning actions. 162 * The {@linkplain java.lang.Thread#getContextClassLoader context class loader} 163 * of the thread is set to the 164 * {@link ClassLoader#getSystemClassLoader() system class loader}. 165 * The thread has no permissions, enforced only if a 166 * {@link java.lang.System#setSecurityManager(SecurityManager) SecurityManager is set}. 167 * <p> 168 * All exceptions thrown by the cleaning actions in this thread are ignored. 169 * <p> 170 * The cleaner terminates when it is phantom reachable and all of the 171 * registered cleaning actions are complete. 172 * 173 * @return a new {@code Cleaner} 174 * 175 * @throws SecurityException if the current thread is not allowed to 176 * create or start the thread. 177 */ create()178 public static Cleaner create() { 179 Cleaner cleaner = new Cleaner(); 180 cleaner.impl.start(cleaner, null); 181 return cleaner; 182 } 183 184 /** 185 * Returns a new {@code Cleaner} using a {@code Thread} from the {@code ThreadFactory}. 186 * <p> 187 * A thread from the thread factory's {@link ThreadFactory#newThread(Runnable) newThread} 188 * method is set to be a {@link Thread#setDaemon(boolean) daemon thread} 189 * and started to process phantom reachable objects and invoke cleaning actions. 190 * On each call the {@link ThreadFactory#newThread(Runnable) thread factory} 191 * must provide a Thread that is suitable for performing the cleaning actions. 192 * <p> 193 * The cleaner terminates when it is phantom reachable and all of the 194 * registered cleaning actions are complete. 195 * 196 * @param threadFactory a {@code ThreadFactory} to return a new {@code Thread} 197 * to process cleaning actions 198 * @return a new {@code Cleaner} 199 * 200 * @throws IllegalThreadStateException if the thread from the thread 201 * factory was {@link Thread.State#NEW not a new thread}. 202 * @throws SecurityException if the current thread is not allowed to 203 * create or start the thread. 204 */ create(ThreadFactory threadFactory)205 public static Cleaner create(ThreadFactory threadFactory) { 206 Objects.requireNonNull(threadFactory, "threadFactory"); 207 Cleaner cleaner = new Cleaner(); 208 cleaner.impl.start(cleaner, threadFactory); 209 return cleaner; 210 } 211 212 // Android-added: objects registered in the system cleaner are cleaned 213 // by the finalizer daemon thread, not in a InnocuousThread. 214 /** 215 * Returns a new {@code Cleaner} associated with the finalizer thread. 216 * @hide 217 */ createSystemCleaner()218 public static Cleaner createSystemCleaner() { 219 Cleaner cleaner = new Cleaner(FinalizerReference.queue); 220 cleaner.impl.start(cleaner); 221 return cleaner; 222 } 223 224 /** 225 * Registers an object and a cleaning action to run when the object 226 * becomes phantom reachable. 227 * Refer to the <a href="#compatible-cleaners">API Note</a> above for 228 * cautions about the behavior of cleaning actions. 229 * 230 * @param obj the object to monitor 231 * @param action a {@code Runnable} to invoke when the object becomes phantom reachable 232 * @return a {@code Cleanable} instance 233 */ register(Object obj, Runnable action)234 public Cleanable register(Object obj, Runnable action) { 235 Objects.requireNonNull(obj, "obj"); 236 Objects.requireNonNull(action, "action"); 237 return new CleanerImpl.PhantomCleanableRef(obj, this, action); 238 } 239 240 /** 241 * {@code Cleanable} represents an object and a 242 * cleaning action registered in a {@code Cleaner}. 243 * @since 9 244 */ 245 public interface Cleanable { 246 /** 247 * Unregisters the cleanable and invokes the cleaning action. 248 * The cleanable's cleaning action is invoked at most once 249 * regardless of the number of calls to {@code clean}. 250 */ clean()251 void clean(); 252 } 253 254 } 255