Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8189386

(ref) Deprecate Reference.isEnqueued()

    XMLWordPrintable

Details

    • CSR
    • Resolution: Approved
    • P3
    • 16
    • core-libs
    • None
    • minimal
    • No change to the existing behavior.
    • Java API
    • SE

    Description

      Summary

      Fix the specification of Reference::isEnqueued method to match the long-standing implementation and also add deprecation.

      Problem

      The Reference::isEnqueued method was never implemented as it was initially specified since 1.2. The specification says that it tests if this reference object has been enqueued, but the long-standing behavior is to test if this reference object is in its associated queue, only reflecting the state at the time when this method is executed. The implementation doesn't do what the specification promised, which might cause serious bugs if unnoticed. For example, an application that relies on this method to release critical resources could cause serious performance issues, in particular when this method is misused on Reference objects without an associated queue (See JDK-8188055 for the enhancement request).

      Solution

      This method may be used for testing or debugging purposes; otherwise, its usefulness is very limited. Survey on some existing uses from grepcode shows that it is used unnecessarily in some places (e.g. r.get() != null && !r.isEnqueued() to check if a reference is not cleared). This proposes to deprecate this method to raise developers' attention that existing uses should be examined for correctness. In addition, the specification of Reference::isEnqueued should be corrected to match the long-standing current behavior.

      An alternative considered was to fix the implementation to return true when a reference object has been enqueued in its associated queue. The behavioral change may impact existing applications of the current behavior. There is no good use case of this method but misuses of this method on reference objects without its associated queue are observed. It's not worth risking an incompatible behavioral change, hence this proposal to correct the specification along with deprecation.

      Specification

      Deprecate Reference::isEnqueued method.

      The following is the updated javadoc of this Reference::isEnqueued method to match the long-standing implementation.

      --- a/src/java.base/share/classes/java/lang/ref/Reference.java
      +++ b/src/java.base/share/classes/java/lang/ref/Reference.java
      @@ -411,14 +411,35 @@ public abstract class Reference<T> {
           /* -- Queue operations -- */
      
           /**
      -     * Tells whether or not this reference object has been enqueued, either by
      -     * the program or by the garbage collector.  If this reference object was
      -     * not registered with a queue when it was created, then this method will
      -     * always return {@code false}.
      -     *
      -     * @return   {@code true} if and only if this reference object has
      -     *           been enqueued
      +     * Tests if this reference object is in its associated queue, if any.
      +     * This method returns {@code true} only if all of the following conditions
      +     * are met:
      +     * <ul>
      +     * <li>this reference object was registered with a queue when it was created; and
      +     * <li>the garbage collector has added this reference object to the queue
      +     *     or {@link #enqueue()} is called; and
      +     * <li>this reference object is not yet removed from the queue.
      +     * </ul>
      +     * Otherwise, this method returns {@code false}.
      +     * This method may return {@code false} if this reference object has been cleared
      +     * but not enqueued due to the race condition.
      +     *
      +     * @deprecated
      +     * This method was never implemented to test if a reference object has
      +     * been cleared and enqueued as it was previously specified since 1.2.
      +     * This method could be misused due to the inherent race condition
      +     * or without an associated {@code ReferenceQueue}.
      +     * An application relying on this method to release critical resources
      +     * could cause serious performance issue.
      +     * An application should use {@link ReferenceQueue} to reliably determine
      +     * what reference objects that have been enqueued or
      +     * {@link #refersTo(Object) refersTo(null)} to determine if this reference
      +     * object has been cleared.
      +     *
      +     * @return   {@code true} if and only if this reference object is
      +     *           in its associated queue (if any).
            */
      +    @Deprecated(since="16")
           public boolean isEnqueued() {
               return (this.queue == ReferenceQueue.ENQUEUED);
           }

      Attachments

        Issue Links

          Activity

            People

              mchung Mandy Chung
              kbarrett Kim Barrett
              Kim Barrett
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: