1 /*
   2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   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 
  29 /**
  30  * {@code Ephemeron<K, V>} objects are a special kind of {@code WeakReference<K>}
  31  * objects, which hold two referents (a normal referent, also called a key referent,
  32  * and a value referent) and do not prevent their referents from being made
  33  * finalizable, finalized, and then  reclaimed. In addition to the key referent,
  34  * which adheres to the referent behavior of a {@code WeakReference<K>},
  35  * an ephemeron also holds a value referent whose reachabiliy strength is affected
  36  * by the reachability strength of the key referent. The value referent of an
  37  * Ephemeron instance is considered:
  38  * <ul>
  39  * <li><em>strongly reachable</em> if the key referent of the same Ephemeron
  40  * object is strongly reachable, or if the value referent is otherwise strongly
  41  * reachable.
  42  * </li>
  43  * <li><em>softly reachable</em> if it is not strongly reachable, and the key referent of
  44  * the same Ephemeron object is softly reachable, or if the value referent is
  45  * otherwise softly reachable.
  46  * </li>
  47  * <li><em>weakly reachable</em> if it is neither strongly nor softly reachable, and the
  48  * key referent of the same Ephemeron object is weakly reachable, or if the value
  49  * referent is otherwise  weakly reachable.
  50  * </li>
  51  * </ul>
  52  * <p>When the collector clears an Ephemeron object instance (according to the rules
  53  * expressed for clearing WeakReference object instances), the Ephemeron instance's
  54  * key referent and value referent are simultaneously and atomically cleared.
  55  * <p>By convenience, the Ephemeron's normal referent is also called the key referent,
  56  * and can be obtained either by invoking {@link #get} or {@link #getKey} while
  57  * the value referent can be obtained by invoking {@link #getValue} method.
  58  * <h3>Reachability (should be moved to package-level docs)</h3>
  59  * Going from strongest to weakest, the different levels of
  60  * reachability reflect the life cycle of an object.  They are
  61  * operationally defined as follows:
  62  * <ul>
  63  * <li>An object is <em>strongly reachable</em> if it can be reached by some thread
  64  * without traversing any reference objects, or by traversing the value of an Ephemeron
  65  * whose key is strongly reachable. A newly-created object is strongly reachable by
  66  * the thread that created it
  67  * </li>
  68  * <li>An object is <em>softly reachable</em> if it is not strongly reachable but
  69  * can be reached by traversing a soft reference or by traversing the value of an
  70  * Ephemeron whose key is softly reachable.
  71  * </li>
  72  * <li>An object is <em>weakly reachable</em> if it is neither strongly nor softly
  73  * reachable but can be reached by traversing a weak reference or by traversing the
  74  * value of an ephemeron whose key is weakly reachable. When the weak references
  75  * to a weakly-reachable object are cleared, the object becomes eligible for
  76  * finalization.
  77  * </li>
  78  * <li>An object is <em>phantom reachable</em> if it is neither
  79  * strongly, softly, nor weakly reachable, it has been finalized, and
  80  * some phantom reference refers to it.
  81  * </li>
  82  * <li>Finally, an object is <em>unreachable</em>, and therefore
  83  * eligible for reclamation, when it is not reachable in any of the
  84  * above ways.
  85  * </li>
  86  * </ul>
  87  *
  88  * @since 9
  89  */
  90 
  91 public class Ephemeron<K, V> extends WeakReference<K> {
  92 
  93     /**
  94      * The value field is treated specially by GC
  95      */
  96     private V value;
  97 
  98     /**
  99      * Creates a new ephemeron that refers to the given key and
 100      * given value. The new ephemeron is not registered with any queue.
 101      *
 102      * @param key   the key (or referent) the new ephemeron will refer to
 103      * @param value the value the new ephemeron will hold until cleared
 104      */
 105     public Ephemeron(K key, V value) {
 106         super(key);
 107         this.value = value;
 108     }
 109 
 110     /**
 111      * Creates a new ephemeron that refers to the given key and
 112      * given value and is registered with the given queue.
 113      *
 114      * @param key   the key (or referent) the new ephemeron will refer to
 115      * @param value the value the new ephemeron will hold until cleared
 116      * @param q     the queue with which the ephemeron is to be registered,
 117      *              or {@code null} if registration is not required
 118      */
 119     public Ephemeron(K key, V value, ReferenceQueue<? super K> q) {
 120         super(key, q);
 121         this.value = value;
 122     }
 123 
 124     /**
 125      * Returns this ephemeron object's referent, also known as the key.
 126      * If this ephemeron object has been cleared, either by the program or by
 127      * the garbage collector, then this method returns <code>null</code>.
 128      *
 129      * @return The key object to which this ephemeron object refers, or
 130      * <code>null</code> if this ephemeron object has been cleared
 131      * @see #getValue()
 132      */
 133     public K getKey() {
 134         return get();
 135     }
 136 
 137     /**
 138      * Returns this ephemeron object's value.
 139      * If this ephemeron object has been cleared, either by the program or by
 140      * the garbage collector, then this method returns <code>null</code>.
 141      *
 142      * @return The value object to which this ephemeron object refers, or
 143      * <code>null</code> if this ephemeron object has been cleared
 144      * @see #getKey()
 145      */
 146     public V getValue() {
 147         return value;
 148     }
 149 
 150     /**
 151      * Clears this ephemeron object, resetting both the key and
 152      * the value to null.  Invoking this method will not cause this
 153      * ephemeron object to be enqueued.
 154      * <p> This method is invoked only by Java code; when the garbage collector
 155      * clears ephemerons it does so directly, without invoking this method.
 156      */
 157     @Override
 158     public void clear() {
 159         super.clear();
 160         this.value = null;
 161     }
 162 }