diff --git a/src/java.base/share/classes/java/lang/ref/Reference.java b/src/java.base/share/classes/java/lang/ref/Reference.java index 655cc6b73761f..ae5d9a7661377 100644 --- a/src/java.base/share/classes/java/lang/ref/Reference.java +++ b/src/java.base/share/classes/java/lang/ref/Reference.java @@ -481,8 +481,12 @@ public boolean isEnqueued() { } /** - * Clears this reference object and adds it to the queue with which - * it is registered, if any. + * Clears this reference object, then attempts to add it to the queue with + * which it is registered, if any. + * + *
If this reference was already enqueued (by the garbage collector, or a + * previous call to {@code enqueue}), this method is not successful, + * and returns false. * *
Memory consistency effects: Actions in a thread prior to calling * {@code enqueue} successfully @@ -490,24 +494,15 @@ public boolean isEnqueued() { * the reference is removed from the queue by {@link ReferenceQueue#poll} * or {@link ReferenceQueue#remove}. * - * There is a potential race condition with the garbage collector. - * When this method is called, the garbage collector - * may already be in the process of (or already completed) - * enqueueing this reference. - * - * This can result in an - * unsuccessful {@code enqueue()}. - * - * - * Avoid this race by ensuring the referent remains strongly-reachable until after the call to clear(), using {@link #reachabilityFence(Object)} if necessary. - * - * - *
This method is invoked only by Java code; when the garbage collector + *
This method is invoked only by Java code; when the garbage collector * enqueues references it does so directly, without invoking this method. * * @apiNote - * Unexpected behavior can result if this method is called while the - * referent is still in use. + * Use of this method allows the registered queue's + * {@link ReferenceQueue#poll} and {@link ReferenceQueue#remove} methods + * to return this reference even though the referent is still strongly + * reachable. That is, before the referent has reached the expected + * reachability level. * * @return {@code true} if this reference object was successfully * enqueued; {@code false} if it was already enqueued or if diff --git a/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java b/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java index de49b9a5e9736..e2484dea0f138 100644 --- a/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java +++ b/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java @@ -180,6 +180,12 @@ boolean enqueue(Reference extends T> r) { /* Called only by Reference class */ * available without further delay then it is removed from the queue and * returned. Otherwise this method immediately returns {@code null}. * + * @apiNote + * If the returned reference was added to this queue by a call to + * {@link Reference#enqueue()} instead of by the garbage collector, its + * former referent (which has since been cleared) could still be strongly + * reachable. + * * @return A reference object, if one was immediately available, * otherwise {@code null} */ @@ -201,6 +207,12 @@ public Reference extends T> poll() { *
This method does not offer real-time guarantees: It schedules the * timeout as if by invoking the {@link Object#wait(long)} method. * + * @apiNote + * If the returned reference was added to this queue by a call to + * {@link Reference#enqueue()} instead of by the garbage collector, its + * former referent (which has since been cleared) could still be strongly + * reachable. + * * @param timeout If positive, block for up to {@code timeout} * milliseconds while waiting for a reference to be * added to this queue. If zero, block indefinitely. @@ -232,6 +244,12 @@ public Reference extends T> remove(long timeout) throws InterruptedException { * Removes the next reference object in this queue, blocking until one * becomes available. * + * @apiNote + * If the returned reference was added to this queue by a call to + * {@link Reference#enqueue()} instead of by the garbage collector, its + * former referent (which has since been cleared) could still be strongly + * reachable. + * * @return A reference object, blocking until one becomes available * @throws InterruptedException If the wait is interrupted */