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  * Ephemeron objects are a special kind of Reference objects, which do not prevent
  31  * their referents, also called keys, from being made finalizable, finalized, and
  32  * then reclaimed. In addition to the key, an ephemeron also holds a value which
  33  * is treated specially by garbage collector. Unless the value is reachable in some
  34  * other way other than through the ephemeron, it is considered
  35  * weakly reachable if and only if the key of the same ephemeron is
  36  * strongly, softly, or weakly reachable otherwise the value is
  37  * considered ephemerally reachable.
  38  * <p> Suppose that the garbage collector determines at a certain point in time
  39  * that an object is ephemerally reachable.
  40  * At that time it will atomically clear all ephemerons that refer to this object
  41  * through their keys and all ephemerons that refer to other ephemerally-reachable
  42  * objects from which that object is reachable through a chain of strong, soft or
  43  * weak references.
  44  * At the same time garbage collector will declare all of the formerly
  45  * ephemerally-reachable objects to be finalizable.  At the same time or at some
  46  * later time it will enqueue those newly-cleared ephemerons that are
  47  * registered with reference queues.
  48  * <p> By convenience, the Ephemeron's referent is also called the key, and can be
  49  * obtained either by invoking {@link #get} or {@link #getKey} while the value
  50  * can be obtained by invoking {@link #getValue} method.
  51  * <a name="reachability"></a>
  52  * <h3>Reachability</h3>
  53  * Going from strongest to weakest, the different levels of
  54  * reachability reflect the life cycle of an object.  They are
  55  * operationally defined as follows:
  56  * <ul>
  57  * <li> An object is <em>strongly reachable</em> if it can be reached
  58  * by some thread without traversing any reference objects.  A
  59  * newly-created object is strongly reachable by the thread that
  60  * created it.
  61  * <li> An object is <em>softly reachable</em> if it is not strongly
  62  * reachable but can be reached by traversing a soft reference.
  63  * <li> An object is <em>weakly reachable</em> if it is neither
  64  * strongly nor softly reachable but can be reached by traversing a
  65  * weak reference or by traversing an ephemeron through it's value while
  66  * the ephemeron's key is at least weakly reachable.
  67  * <li> An object is <em>ephemerally reachable</em> if it is neither
  68  * strongly, softly nor weakly reachable but can be reached by traversing an
  69  * ephemeron through it's key or by traversing an ephemeron through it's value
  70  * while it's key is at most ephemerally reachable. When the ephemerons that
  71  * refer to ephemerally reachable key object are cleared, the key object becomes
  72  * eligible for finalization.
  73  * <li> An object is <em>phantom reachable</em> if it is neither
  74  * strongly, softly, weakly not ephemerally reachable, it has been finalized,
  75  * and some phantom reference refers to it.
  76  * <li> Finally, an object is <em>unreachable</em>, and therefore
  77  * eligible for reclamation, when it is not reachable in any of the
  78  * above ways.
  79  * </ul>
  80  *
  81  * @author Peter Levart
  82  * @since 9
  83  */
  84 
  85 public class Ephemeron<K, V> extends Reference<K> {
  86 
  87     /**
  88      * The value field is treated specially by GC
  89      */
  90     private V value;
  91 
  92     /**
  93      * Creates a new ephemeron that refers to the given key and
  94      * given value. The new ephemeron is not registered with any queue.
  95      *
  96      * @param key   the key (or referent) the new ephemeron will refer to
  97      * @param value the value the new ephemeron will hold until cleared
  98      */
  99     public Ephemeron(K key, V value) {
 100         super(key);
 101         this.value = value;
 102     }
 103 
 104     /**
 105      * Creates a new ephemeron that refers to the given key and
 106      * given value and is registered with the given queue.
 107      *
 108      * @param key   the key (or referent) the new ephemeron will refer to
 109      * @param value the value the new ephemeron will hold until cleared
 110      * @param q     the queue with which the ephemeron is to be registered,
 111      *              or {@code null} if registration is not required
 112      */
 113     public Ephemeron(K key, V value, ReferenceQueue<? super K> q) {
 114         super(key, q);
 115         this.value = value;
 116     }
 117 
 118     /**
 119      * Returns this ephemeron object's referent, also known as the key.
 120      * If this ephemeron object has been cleared, either by the program or by
 121      * the garbage collector, then this method returns <code>null</code>.
 122      *
 123      * @return The key object to which this ephemeron object refers, or
 124      * <code>null</code> if this ephemeron object has been cleared
 125      * @see #getValue()
 126      */
 127     public K getKey() {
 128         return get();
 129     }
 130 
 131     /**
 132      * Returns this ephemeron object's value.
 133      * If this ephemeron object has been cleared, either by the program or by
 134      * the garbage collector, then this method returns <code>null</code>.
 135      *
 136      * @return The value object to which this ephemeron object refers, or
 137      * <code>null</code> if this ephemeron object has been cleared
 138      * @see #getKey()
 139      */
 140     public V getValue() {
 141         return value;
 142     }
 143 
 144     /**
 145      * Clears this ephemeron object, resetting both the key and
 146      * the value to null.  Invoking this method will not cause this
 147      * ephemeron object to be enqueued.
 148      * <p> This method is invoked only by Java code; when the garbage collector
 149      * clears ephemerons it does so directly, without invoking this method.
 150      */
 151     @Override
 152     public void clear() {
 153         super.clear();
 154         this.value = null;
 155     }
 156 }