Skip to content

Commit

Permalink
Update enqueue() docs, add warnings about still-reachable referent
Browse files Browse the repository at this point in the history
  • Loading branch information
bchristi-git committed Sep 26, 2023
1 parent 523c2bb commit fbc8fc3
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 17 deletions.
29 changes: 12 additions & 17 deletions src/java.base/share/classes/java/lang/ref/Reference.java
Original file line number Diff line number Diff line change
Expand Up @@ -481,33 +481,28 @@ 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.
*
* <p>If this reference was already enqueued (by the garbage collector, or a
* previous call to {@code enqueue}), this method is <b><i>not successful</i></b>,
* and returns false.
*
* <p>Memory consistency effects: Actions in a thread prior to calling
* {@code enqueue} <b><i>successfully</i></b>
* <a href="{@docRoot}/java.base/java/util/concurrent/package-summary.html#MemoryVisibility"><i>happen-before</i></a>
* 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
* <b><i></i></b>unsuccessful</i></b> {@code enqueue()}.
*
*
* Avoid this race by ensuring the referent remains strongly-reachable until after the call to clear(), using {@link #reachabilityFence(Object)} if necessary.
*
*
* <p> This method is invoked only by Java code; when the garbage collector
* <p>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
Expand Down
18 changes: 18 additions & 0 deletions src/java.base/share/classes/java/lang/ref/ReferenceQueue.java
Original file line number Diff line number Diff line change
Expand Up @@ -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}
*/
Expand All @@ -201,6 +207,12 @@ public Reference<? extends T> poll() {
* <p> 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.
Expand Down Expand Up @@ -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
*/
Expand Down

0 comments on commit fbc8fc3

Please sign in to comment.