< prev index next >

src/java.base/share/classes/java/lang/ref/Cleaner.java

Print this page




  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 /**
  35  * {@code Cleaner} manages a set of object references and corresponding cleaning actions.
  36  * <p>
  37  * Cleaning actions are {@link #register(Object object, Runnable action) registered}
  38  * to run after the cleaner is notified that the object has become
  39  * phantom reachable.
  40  * The cleaner uses {@link PhantomReference} and {@link ReferenceQueue} to be
  41  * notified when the <a href="package-summary.html#reachability">reachability</a>
  42  * changes.
  43  * <p>
  44  * Each cleaner operates independently, managing the pending cleaning actions
  45  * and handling threading and termination when the cleaner is no longer in use.
  46  * Registering an object reference and corresponding cleaning action returns
  47  * a {@link Cleanable Cleanable}. The most efficient use is to explicitly invoke
  48  * the {@link Cleanable#clean clean} method when the object is closed or
  49  * no longer needed.
  50  * The cleaning action is a {@link Runnable} to be invoked at most once when
  51  * the object has become phantom reachable unless it has already been explicitly cleaned.
  52  * Note that the cleaning action must not refer to the object being registered.


 111  *        public void close() {
 112  *            cleanable.clean();
 113  *        }
 114  *    }
 115  * }</pre>
 116  * The cleaning action could be a lambda but all too easily will capture
 117  * the object reference, by referring to fields of the object being cleaned,
 118  * preventing the object from becoming phantom reachable.
 119  * Using a static nested class, as above, will avoid accidentally retaining the
 120  * object reference.
 121  * <p>
 122  * <a name="compatible-cleaners"></a>
 123  * Cleaning actions should be prepared to be invoked concurrently with
 124  * other cleaning actions.
 125  * Typically the cleaning actions should be very quick to execute
 126  * and not block. If the cleaning action blocks, it may delay processing
 127  * other cleaning actions registered to the same cleaner.
 128  * All cleaning actions registered to a cleaner should be mutually compatible.
 129  * @since 9
 130  */
 131 public final class Cleaner {
 132 
 133     /**
 134      * The Cleaner implementation.
 135      */
 136     final CleanerImpl impl;
 137 
 138     static {
 139         CleanerImpl.setCleanerImplAccess(new Function<Cleaner, CleanerImpl>() {
 140             @Override
 141             public CleanerImpl apply(Cleaner cleaner) {
 142                 return cleaner.impl;
 143             }
 144         });
 145     }
 146 
 147     /**
 148      * Construct a Cleaner implementation and start it.
 149      */
 150     private Cleaner() {
 151         impl = new CleanerImpl();
 152     }
 153 
 154     /**
 155      * Returns a new {@code Cleaner}.
 156      * <p>
 157      * The cleaner creates a {@link Thread#setDaemon(boolean) daemon thread}
 158      * to process the phantom reachable objects and to invoke cleaning actions.
 159      * The {@linkplain java.lang.Thread#getContextClassLoader context class loader}
 160      * of the thread is set to the
 161      * {@link ClassLoader#getSystemClassLoader() system class loader}.
 162      * The thread has no permissions, enforced only if a
 163      * {@link java.lang.System#setSecurityManager(SecurityManager) SecurityManager is set}.
 164      * <p>
 165      * The cleaner terminates when it is phantom reachable and all of the
 166      * registered cleaning actions are complete.
 167      *
 168      * @return a new {@code Cleaner}
 169      *
 170      * @throws  SecurityException  if the current thread is not allowed to
 171      *               create or start the thread.
 172      */
 173     public static Cleaner create() {
 174         Cleaner cleaner = new Cleaner();
 175         cleaner.impl.start(cleaner, null);
 176         return cleaner;
 177     }
 178 
 179     /**
 180      * Returns a new {@code Cleaner} using a {@code Thread} from the {@code ThreadFactory}.
 181      * <p>
 182      * A thread from the thread factory's {@link ThreadFactory#newThread(Runnable) newThread}
 183      * method is set to be a {@link Thread#setDaemon(boolean) daemon thread}
 184      * and started to process phantom reachable objects and invoke cleaning actions.
 185      * On each call the {@link ThreadFactory#newThread(Runnable) thread factory}
 186      * must provide a Thread that is suitable for performing the cleaning actions.
 187      * <p>
 188      * The cleaner terminates when it is phantom reachable and all of the
 189      * registered cleaning actions are complete.
 190      *
 191      * @param threadFactory a {@code ThreadFactory} to return a new {@code Thread}
 192      *                      to process cleaning actions
 193      * @return a new {@code Cleaner}
 194      *
 195      * @throws  IllegalThreadStateException  if the thread from the thread
 196      *               factory was {@link Thread.State#NEW not a new thread}.
 197      * @throws  SecurityException  if the current thread is not allowed to
 198      *               create or start the thread.
 199      */
 200     public static Cleaner create(ThreadFactory threadFactory) {
 201         Objects.requireNonNull(threadFactory, "threadFactory");
 202         Cleaner cleaner = new Cleaner();
 203         cleaner.impl.start(cleaner, threadFactory);
 204         return cleaner;
 205     }
 206 
 207     /**
 208      * Registers an object and a cleaning action to run when the object
 209      * becomes phantom reachable.
 210      * Refer to the <a href="#compatible-cleaners">API Note</a> above for
 211      * cautions about the behavior of cleaning actions.
 212      *
 213      * @param obj   the object to monitor
 214      * @param action a {@code Runnable} to invoke when the object becomes phantom reachable
 215      * @return a {@code Cleanable} instance
 216      */
 217     public Cleanable register(Object obj, Runnable action) {
 218         Objects.requireNonNull(obj, "obj");
 219         Objects.requireNonNull(action, "action");
 220         return new CleanerImpl.PhantomCleanableRef(obj, this, action);
 221     }
 222 
 223     /**
 224      * {@code Cleanable} represents an object and a
 225      * cleaning action registered in a {@code Cleaner}.
 226      * @since 9
 227      */
 228     public interface Cleanable {
 229         /**
 230          * Unregisters the cleanable and invokes the cleaning action.
 231          * The cleanable's cleaning action is invoked at most once
 232          * regardless of the number of calls to {@code clean}.
 233          */
 234         void clean();
 235     }
 236 
 237 }


  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 
  33 /**
  34  * {@code Cleaner} manages a set of object references and corresponding cleaning actions.
  35  * <p>
  36  * Cleaning actions are {@link #register(Object object, Runnable action) registered}
  37  * to run after the cleaner is notified that the object has become
  38  * phantom reachable.
  39  * The cleaner uses {@link PhantomReference} and {@link ReferenceQueue} to be
  40  * notified when the <a href="package-summary.html#reachability">reachability</a>
  41  * changes.
  42  * <p>
  43  * Each cleaner operates independently, managing the pending cleaning actions
  44  * and handling threading and termination when the cleaner is no longer in use.
  45  * Registering an object reference and corresponding cleaning action returns
  46  * a {@link Cleanable Cleanable}. The most efficient use is to explicitly invoke
  47  * the {@link Cleanable#clean clean} method when the object is closed or
  48  * no longer needed.
  49  * The cleaning action is a {@link Runnable} to be invoked at most once when
  50  * the object has become phantom reachable unless it has already been explicitly cleaned.
  51  * Note that the cleaning action must not refer to the object being registered.


 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 name="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 interface Cleaner {





















 131 
 132     /**
 133      * Returns a new {@code Cleaner}.
 134      * <p>
 135      * The cleaner creates a {@link Thread#setDaemon(boolean) daemon thread}
 136      * to process the phantom reachable objects and to invoke cleaning actions.
 137      * The {@linkplain java.lang.Thread#getContextClassLoader context class loader}
 138      * of the thread is set to the
 139      * {@link ClassLoader#getSystemClassLoader() system class loader}.
 140      * The thread has no permissions, enforced only if a
 141      * {@link java.lang.System#setSecurityManager(SecurityManager) SecurityManager is set}.
 142      * <p>
 143      * The cleaner terminates when it is phantom reachable and all of the
 144      * registered cleaning actions are complete.
 145      *
 146      * @return a new {@code Cleaner}
 147      *
 148      * @throws  SecurityException  if the current thread is not allowed to
 149      *               create or start the thread.
 150      */
 151     static Cleaner create() {
 152         return new CleanerImpl(null);


 153     }
 154 
 155     /**
 156      * Returns a new {@code Cleaner} using a {@code Thread} from the {@code ThreadFactory}.
 157      * <p>
 158      * A thread from the thread factory's {@link ThreadFactory#newThread(Runnable) newThread}
 159      * method is set to be a {@link Thread#setDaemon(boolean) daemon thread}
 160      * and started to process phantom reachable objects and invoke cleaning actions.
 161      * On each call the {@link ThreadFactory#newThread(Runnable) thread factory}
 162      * must provide a Thread that is suitable for performing the cleaning actions.
 163      * <p>
 164      * The cleaner terminates when it is phantom reachable and all of the
 165      * registered cleaning actions are complete.
 166      *
 167      * @param threadFactory a {@code ThreadFactory} to return a new {@code Thread}
 168      *                      to process cleaning actions
 169      * @return a new {@code Cleaner}
 170      *
 171      * @throws  IllegalThreadStateException  if the thread from the thread
 172      *               factory was {@link Thread.State#NEW not a new thread}.
 173      * @throws  SecurityException  if the current thread is not allowed to
 174      *               create or start the thread.
 175      */
 176     static Cleaner create(ThreadFactory threadFactory) {
 177         Objects.requireNonNull(threadFactory, "threadFactory");
 178         return new CleanerImpl(threadFactory);


 179     }
 180 
 181     /**
 182      * Registers an object and a cleaning action to run when the object
 183      * becomes phantom reachable.
 184      * Refer to the <a href="#compatible-cleaners">API Note</a> above for
 185      * cautions about the behavior of cleaning actions.
 186      *
 187      * @param obj   the object to monitor
 188      * @param action a {@code Runnable} to invoke when the object becomes phantom reachable
 189      * @return a {@code Cleanable} instance
 190      */
 191     Cleanable register(Object obj, Runnable action);




 192 
 193     /**
 194      * {@code Cleanable} represents an object and a
 195      * cleaning action registered in a {@code Cleaner}.
 196      * @since 9
 197      */
 198     interface Cleanable {
 199         /**
 200          * Unregisters the cleanable and invokes the cleaning action.
 201          * The cleanable's cleaning action is invoked at most once
 202          * regardless of the number of calls to {@code clean}.
 203          */
 204         void clean();
 205     }
 206 
 207 }
< prev index next >