/* * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.lang.ref; /** * {@code Ephemeron} objects are a special kind of {@code WeakReference} * objects, which hold two referents (a normal referent, also called a key referent, * and a value referent) and do not prevent their referents from being made * finalizable, finalized, and then reclaimed. In addition to the key referent, * which adheres to the referent behavior of a {@code WeakReference}, * an ephemeron also holds a value referent whose reachabiliy strength is affected * by the reachability strength of the key referent. The value referent of an * Ephemeron instance is considered: *
    *
  • strongly reachable if the key referent of the same Ephemeron * object is strongly reachable, or if the value referent is otherwise strongly * reachable. *
  • *
  • softly reachable if it is not strongly reachable, and the key referent of * the same Ephemeron object is softly reachable, or if the value referent is * otherwise softly reachable. *
  • *
  • weakly reachable if it is neither strongly nor softly reachable, and the * key referent of the same Ephemeron object is weakly reachable, or if the value * referent is otherwise weakly reachable. *
  • *
*

When the collector clears an Ephemeron object instance (according to the rules * expressed for clearing WeakReference object instances), the Ephemeron instance's * key referent and value referent are simultaneously and atomically cleared. *

By convenience, the Ephemeron's normal referent is also called the key referent, * and can be obtained either by invoking {@link #get} or {@link #getKey} while * the value referent can be obtained by invoking {@link #getValue} method. *

Reachability (should be moved to package-level docs)

* Going from strongest to weakest, the different levels of * reachability reflect the life cycle of an object. They are * operationally defined as follows: *
    *
  • An object is strongly reachable if it can be reached by some thread * without traversing any reference objects, or by traversing the value of an Ephemeron * whose key is strongly reachable. A newly-created object is strongly reachable by * the thread that created it *
  • *
  • An object is softly reachable if it is not strongly reachable but * can be reached by traversing a soft reference or by traversing the value of an * Ephemeron whose key is softly reachable. *
  • *
  • An object is weakly reachable if it is neither strongly nor softly * reachable but can be reached by traversing a weak reference or by traversing the * value of an ephemeron whose key is weakly reachable. When the weak references * to a weakly-reachable object are cleared, the object becomes eligible for * finalization. *
  • *
  • An object is phantom reachable if it is neither * strongly, softly, nor weakly reachable, it has been finalized, and * some phantom reference refers to it. *
  • *
  • Finally, an object is unreachable, and therefore * eligible for reclamation, when it is not reachable in any of the * above ways. *
  • *
* * @since 9 */ public class Ephemeron extends WeakReference { /** * The value field is treated specially by GC */ private V value; /** * Creates a new ephemeron that refers to the given key and * given value. The new ephemeron is not registered with any queue. * * @param key the key (or referent) the new ephemeron will refer to * @param value the value the new ephemeron will hold until cleared */ public Ephemeron(K key, V value) { super(key); this.value = value; } /** * Creates a new ephemeron that refers to the given key and * given value and is registered with the given queue. * * @param key the key (or referent) the new ephemeron will refer to * @param value the value the new ephemeron will hold until cleared * @param q the queue with which the ephemeron is to be registered, * or {@code null} if registration is not required */ public Ephemeron(K key, V value, ReferenceQueue q) { super(key, q); this.value = value; } /** * Returns this ephemeron object's referent, also known as the key. * If this ephemeron object has been cleared, either by the program or by * the garbage collector, then this method returns null. * * @return The key object to which this ephemeron object refers, or * null if this ephemeron object has been cleared * @see #getValue() */ public K getKey() { return get(); } /** * Returns this ephemeron object's value. * If this ephemeron object has been cleared, either by the program or by * the garbage collector, then this method returns null. * * @return The value object to which this ephemeron object refers, or * null if this ephemeron object has been cleared * @see #getKey() */ public V getValue() { return value; } /** * Clears this ephemeron object, resetting both the key and * the value to null. Invoking this method will not cause this * ephemeron object to be enqueued. *

This method is invoked only by Java code; when the garbage collector * clears ephemerons it does so directly, without invoking this method. */ @Override public void clear() { super.clear(); this.value = null; } }