home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / lang / ref / Reference.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  10.0 KB  |  269 lines

  1. /*
  2.  * @(#)Reference.java    1.17 98/03/18
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.lang.ref;
  16.  
  17.  
  18. /**
  19.  * The <code>Reference</code> class contains the core abstractions for
  20.  * <em>reference objects</em>.  Reference objects reify references in much the
  21.  * same way that Class objects reify Java classes.  That is, a reference object
  22.  * encapsulates a reference to some other object so that the reference itself
  23.  * may be examined and manipulated like any other object.
  24.  *
  25.  * <p> The methods defined in this class allow a program to be notified some
  26.  * time after the collector detects a change in the <em>reachability</em> of a
  27.  * given object.  They also allow a program to maintain a reference to an
  28.  * object that does not prevent the object from being considered for
  29.  * reclamation by the garbage collector.
  30.  *
  31.  * <p> Three types of reference objects are supported, each weaker than the
  32.  * last: <em>guarded</em>, <em>weak</em>, and <em>phantom</em>.  Each type
  33.  * corresponds to a different level of reachability, as defined below.  Guarded
  34.  * references are for implementing sophisticated caches, weak references are
  35.  * for implementing simple caches as well as mappings that do not prevent their
  36.  * keys (or values) from being reclaimed, and phantom references are for
  37.  * scheduling pre-mortem cleanup actions in a more flexible way than is
  38.  * possible with the Java finalization mechanism.
  39.  *
  40.  * <p> Each reference-object type is implemented by subclass of the
  41.  * <code>Reference</code> class.  An instance of one of these subclasses
  42.  * encapsulates a single reference to a particular object, called the
  43.  * <em>referent</em>.  Each subclass provides methods for getting, setting, and
  44.  * clearing the reference.  A program may further subclass these subclasses,
  45.  * adding whatever fields and methods are required for its purposes, or it may
  46.  * use these subclasses without change.
  47.  *
  48.  * <h4>Notification</h4>
  49.  *
  50.  * A program may request to be notified of changes in an object's reachability
  51.  * by <em>registering</em> an appropriate reference object with a <em>reference
  52.  * queue</em> at the time the reference object is created.  Some time after the
  53.  * garbage collector determines that the reachability of the referent has
  54.  * changed to the value corresponding to the type of the reference, it will add
  55.  * the reference to the associated queue.  At this point, the reference is
  56.  * considered to be <em>enqueued</em>.  The program may remove references from
  57.  * a queue either by polling or by blocking until a reference becomes
  58.  * available.  Reference queues are implemented by the
  59.  * <code>ReferenceQueue</code> class.
  60.  *
  61.  * <p> The relationship between a registered reference object and its queue is
  62.  * one-sided.  That is, a queue does not keep track of the references that are
  63.  * registered with it.  If a registered reference becomes unreachable itself,
  64.  * then it will never be enqueued.  It is the responsibility of the program
  65.  * using reference objects to ensure that the objects remain reachable for as
  66.  * long as the program is interested in their referents.
  67.  *
  68.  * <p> While some programs will choose to dedicate a thread to removing
  69.  * reference objects from one or more queues and processing them, this is by no
  70.  * means necessary.  A tactic that often works well is to examine a reference
  71.  * queue in the course of performing some other fairly-frequent action.  For
  72.  * example, a hashtable that uses weak references to implement weak keys could
  73.  * poll its reference queue each time the table is accessed.  Because the
  74.  * <code>poll</code> method simply checks an internal data structure, this
  75.  * check will add little overhead to the hashtable access methods.
  76.  *
  77.  * <h4>Weak references</h4>
  78.  *
  79.  * A weak reference is automatically cleared by the collector at the same time
  80.  * it is added to the queue with which it is registered, if any.  If there is
  81.  * more than one weak reference to an object, all such references will be
  82.  * cleared (and enqueued, if need be) simultaneously and atomically from the
  83.  * standpoint of the program.  Thus weak references need not be registered with
  84.  * a queue in order to be useful, while guarded and phantom references do.
  85.  * Similarly, an object that is reachable via guarded (or phantom) references
  86.  * will remain so until all such references are cleared, are modified to refer
  87.  * to some other object, or themselves become unreachable.
  88.  *
  89.  * <h4>Reachability</h4>
  90.  *
  91.  * Going from strongest to weakest, the different levels of reachability reflect
  92.  * the life cycle of an object.  They are operationally defined as follows:
  93.  *
  94.  * <ul>
  95.  *
  96.  * <li> An object is <em>strongly reachable</em> if it can be reached by some
  97.  * thread without traversing any reference objects.  A newly-created object is
  98.  * strongly reachable by the thread that created it.
  99.  *
  100.  * <li> An object is <em>guardedly reachable</em> if it is not strongly
  101.  * reachable but can be reached by traversing a guarded reference.
  102.  *
  103.  * <li> An object is <em>weakly reachable</em> if it is not guardedly reachable
  104.  * but can be reached by traversing a weak reference.  When the weak references
  105.  * to a weakly-reachable object are cleared, the object becomes eligible for
  106.  * finalization.
  107.  *
  108.  * <li> Finally, an object is <em>phantom reachable</em> if it is not weakly
  109.  * reachable, it has been finalized, and some phantom reference refers to it.
  110.  * An object becomes <em>unreachable</em>, and eligible for reclamation, when
  111.  * the last phantom reference to it is cleared or becomes unreachable itself.
  112.  *
  113.  * </ul>
  114.  *
  115.  * <p> The <code>SoftReference</code> class defines a fifth type of reference
  116.  * object that is cleared only when the runtime system detects that memory is
  117.  * running low.
  118.  *
  119.  * @version     1.17, 98/03/18
  120.  * @author    Mark Reinhold
  121.  * @since    JDK1.2
  122.  * @see         java.lang.Runtime.MemoryAdvice
  123.  * @see         java.lang.ref.ReferenceQueue
  124.  * @see         java.lang.ref.GuardedReference
  125.  * @see         java.lang.ref.WeakReference
  126.  * @see         java.lang.ref.PhantomReference
  127.  * @see         java.lang.ref.SoftReference
  128.  */
  129.  
  130. public abstract class Reference {
  131.  
  132.     private Object referent;        /* Treated specially by GC */
  133.     ReferenceQueue queue = null;
  134.     Reference nextPending = null;    /* For pending-Reference list */
  135.  
  136.  
  137.     /* A Reference is in one of the following three internal states.
  138.        References in the IDLE and ENQUEUED states are treated as normal objects
  139.        by the collector.  The referent field of a Reference in the ACTIVE state
  140.        is treated specially by the collector according to the type of the
  141.        Reference.  When the collector detects that the reachability of the
  142.        referent has changed appropriately, it changes the state to ENQUEUED and
  143.        adds the Reference to the pending-Reference list. */
  144.  
  145.     static final int IDLE = 0;
  146.     static final int ACTIVE = 1;
  147.     static final int ENQUEUED = 2;
  148.  
  149.     int state = IDLE;
  150.  
  151.  
  152.     /* Object used to synchronize with the garbage collector.  The collector
  153.        must acquire this lock at the beginning of each collection cycle.  It is
  154.        therefore critical that any code holding this lock complete as quickly
  155.        as possible, allocate no new objects, and avoid calling user code. */
  156.  
  157.     static private class Lock { };
  158.     private static Lock lock = new Lock();
  159.  
  160.  
  161.     /* List of References waiting to be enqueued.  The collector adds
  162.        References to this list, while the Reference-handler thread removes
  163.        them.  This list is protected by the above lock object. */
  164.  
  165.     private static Reference pending = null;
  166.  
  167.  
  168.     /* High-priority thread to enqueue pending References */
  169.     private static Thread handler = new ReferenceHandler();
  170.  
  171.     private static class ReferenceHandler extends Thread {
  172.  
  173.     public void run() {
  174.         for (;;) {
  175.  
  176.         Reference r;
  177.         synchronized (lock) {
  178.             if (pending != null) {
  179.             r = pending;
  180.             pending = r.nextPending;
  181.             r.nextPending = null;
  182.             } else {
  183.             try {
  184.                 lock.wait();
  185.             } catch (InterruptedException x) { }
  186.             continue;
  187.             }
  188.         }
  189.  
  190.         ReferenceQueue q = r.queue;
  191.         if (q != null) {
  192.             q.enqueue(r);
  193.         } else {
  194.             if (r instanceof WeakReference)
  195.             r.state = ACTIVE;
  196.             else
  197.             r.state = IDLE;
  198.         }
  199.  
  200.         }
  201.     }
  202.     }
  203.  
  204.     static {
  205.     handler.setName("Reference handler");
  206.     /* If there were a special system-only priority greater than
  207.        MAX_PRIORITY, it would be used here */
  208.     handler.setPriority(Thread.MAX_PRIORITY);
  209.     handler.setDaemon(true);
  210.     handler.start();
  211.     }
  212.  
  213.  
  214.     /* -- Referent accessor and setters -- */
  215.  
  216.     /**
  217.      * Return the object to which this reference object refers.  If this
  218.      * reference has been cleared, either by the program or by the garbage
  219.      * collector, then return <code>null</code>.
  220.      */
  221.     public Object get() {
  222.     return this.referent;
  223.     }
  224.  
  225.     /**
  226.      * Clear this reference object.
  227.      */
  228.     public void clear() {
  229.     this.referent = null;
  230.     }
  231.  
  232.  
  233.     /* -- Queue operations -- */
  234.  
  235.     /**
  236.      * Tell whether or not this reference object has been enqueued.  If this
  237.      * reference object was not registered with a queue when it was created,
  238.      * then this method will always return <code>false</code>.
  239.      */
  240.     public boolean isEnqueued() {
  241.     return (this.state == ENQUEUED);
  242.     }
  243.  
  244.     /**
  245.      * Add this reference to the queue with which it was registered.  Return
  246.      * <code>true</code> if this was done successfully; return
  247.      * <code>false</code> if the reference had already been enqueued, or if it
  248.      * had never been registered with a queue.
  249.      */
  250.     public boolean enqueue() {
  251.     ReferenceQueue q = this.queue;
  252.     if (q == null) return false;
  253.     return q.enqueue(this);
  254.     }
  255.  
  256.  
  257.     /* -- Constructors -- */
  258.  
  259.     protected Reference(Object referent) {
  260.     this.referent = referent;
  261.     }
  262.  
  263.     protected Reference(Object referent, ReferenceQueue queue) {
  264.     this(referent);
  265.     this.queue = queue;
  266.     }
  267.  
  268. }
  269.