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 java.util.Objects;
29 import java.util.concurrent.ThreadFactory;
30
31 import jdk.internal.ref.CleanerImpl;
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.
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 final class Cleaner {
131
132 /**
133 * The Cleaner implementation.
134 */
135 final CleanerImpl impl;
136
137 static {
138 CleanerImpl.setCleanerImplAccess((Cleaner c) -> c.impl);
139 }
140
141 /**
142 * Construct a Cleaner implementation and start it.
143 */
144 private Cleaner() {
145 impl = new CleanerImpl();
146 }
147
148 /**
149 * Returns a new {@code Cleaner}.
150 * <p>
151 * The cleaner creates a {@link Thread#setDaemon(boolean) daemon thread}
152 * to process the phantom reachable objects and to invoke cleaning actions.
153 * The {@linkplain java.lang.Thread#getContextClassLoader context class loader}
154 * of the thread is set to the
155 * {@link ClassLoader#getSystemClassLoader() system class loader}.
156 * The thread has no permissions, enforced only if a
157 * {@link java.lang.System#setSecurityManager(SecurityManager) SecurityManager is set}.
158 * <p>
195 Objects.requireNonNull(threadFactory, "threadFactory");
196 Cleaner cleaner = new Cleaner();
197 cleaner.impl.start(cleaner, threadFactory);
198 return cleaner;
199 }
200
201 /**
202 * Registers an object and a cleaning action to run when the object
203 * becomes phantom reachable.
204 * Refer to the <a href="#compatible-cleaners">API Note</a> above for
205 * cautions about the behavior of cleaning actions.
206 *
207 * @param obj the object to monitor
208 * @param action a {@code Runnable} to invoke when the object becomes phantom reachable
209 * @return a {@code Cleanable} instance
210 */
211 public Cleanable register(Object obj, Runnable action) {
212 Objects.requireNonNull(obj, "obj");
213 Objects.requireNonNull(action, "action");
214 return new CleanerImpl.PhantomCleanableRef(obj, this, action);
215 }
216
217 /**
218 * {@code Cleanable} represents an object and a
219 * cleaning action registered in a {@code Cleaner}.
220 * @since 9
221 */
222 public interface Cleanable {
223 /**
224 * Unregisters the cleanable and invokes the cleaning action.
225 * The cleanable's cleaning action is invoked at most once
226 * regardless of the number of calls to {@code clean}.
227 */
228 void clean();
229 }
230
231 }
|
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 /**
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.
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>
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 * Helps the background cleaning thread by invoking next cleaning action
225 * {@link #register(Object, Runnable) registered} by this Cleaner and for
226 * which GC has determined that the monitored object is phantom reachable.
227 *
228 * @return {@code true} if next cleaning action was invoked by this method or
229 * {@code false} if there was no cleaning action registered by this Cleaner
230 * for which GC had determined that its monitored object was phantom reachable.
231 *
232 * @implNote Normally this method needs not be called as cleaning actions are
233 * executed by a background thread. But in some situations, when cleaning
234 * actions take relatively long time to complete and are not invoked explicitly
235 * by calling {@link Cleanable#clean()}, it might be necessary to help the
236 * background thread when it can't keep-up with the rate of registration of
237 * new cleaning actions.
238 * <p>
239 * For example, a program can decide to help with cleanup after it fails to
240 * allocate some limited resource for which it registered cleaning actions.
241 * After giving some help to the background thread, it can re-try to allocate
242 * the resource. Such strategy devotes more CPU time to cleanup when needed
243 * and provides back-pressure to threads allocating the limited resource.
244 */
245 boolean cleanNextPending() {
246 return impl.cleanNextPending();
247 }
248
249 /**
250 * {@code Cleanable} represents an object and a
251 * cleaning action registered in a {@code Cleaner}.
252 * @since 9
253 */
254 public interface Cleanable {
255 /**
256 * Unregisters the cleanable and invokes the cleaning action.
257 * The cleanable's cleaning action is invoked at most once
258 * regardless of the number of calls to {@code clean}.
259 */
260 void clean();
261 }
262
263 }
|