jdk/src/share/classes/java/lang/ref/Reference.java
author mchung
Mon, 08 Jul 2013 14:05:59 +0200
changeset 18815 5da35ed47cfa
parent 17716 f9486b530c80
child 19053 69648476a89e
permissions -rw-r--r--
8014890: (ref) Reference queues may return more entries than expected Summary: When enqueuing references check whether the j.l.r.Reference has already been enqeued or removed in the lock. Do not enqueue them again. This occurs because multiple threads may try to enqueue the same j.l.r.Reference at the same time. Reviewed-by: mchung, dholmes, plevart, shade Contributed-by: thomas.schatzl@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
17716
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
     2
 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package java.lang.ref;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import sun.misc.Cleaner;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * Abstract base class for reference objects.  This class defines the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * operations common to all reference objects.  Because reference objects are
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * implemented in close cooperation with the garbage collector, this class may
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * not be subclassed directly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * @author   Mark Reinhold
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * @since    1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
public abstract class Reference<T> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
    /* A Reference instance is in one of four possible internal states:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
     *     Active: Subject to special treatment by the garbage collector.  Some
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
     *     time after the collector detects that the reachability of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
     *     referent has changed to the appropriate state, it changes the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
     *     instance's state to either Pending or Inactive, depending upon
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
     *     whether or not the instance was registered with a queue when it was
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
     *     created.  In the former case it also adds the instance to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
     *     pending-Reference list.  Newly-created instances are Active.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
     *     Pending: An element of the pending-Reference list, waiting to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
     *     enqueued by the Reference-handler thread.  Unregistered instances
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
     *     are never in this state.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
     *     Enqueued: An element of the queue with which the instance was
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
     *     registered when it was created.  When an instance is removed from
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
     *     its ReferenceQueue, it is made Inactive.  Unregistered instances are
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
     *     never in this state.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
     *     Inactive: Nothing more to do.  Once an instance becomes Inactive its
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
     *     state will never change again.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
     * The state is encoded in the queue and next fields as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
     *     Active: queue = ReferenceQueue with which instance is registered, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
     *     ReferenceQueue.NULL if it was not registered with a queue; next =
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
     *     null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
     *     Pending: queue = ReferenceQueue with which instance is registered;
10895
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
    71
     *     next = this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
     *     Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
     *     in queue, or this if at end of list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
     *     Inactive: queue = ReferenceQueue.NULL; next = this.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
     * With this scheme the collector need only examine the next field in order
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
     * to determine whether a Reference instance requires special treatment: If
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
     * the next field is null then the instance is active; if it is non-null,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     * then the collector should treat the instance normally.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
     *
10895
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
    83
     * To ensure that a concurrent collector can discover active Reference
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
     * objects without interfering with application threads that may apply
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
     * the enqueue() method to those objects, collectors should link
10895
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
    86
     * discovered objects through the discovered field. The discovered
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
    87
     * field is also used for linking Reference objects in the pending list.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    private T referent;         /* Treated specially by GC */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
18815
5da35ed47cfa 8014890: (ref) Reference queues may return more entries than expected
mchung
parents: 17716
diff changeset
    92
    volatile ReferenceQueue<? super T> queue;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
10895
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
    94
    /* When active:   NULL
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
    95
     *     pending:   this
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
    96
     *    Enqueued:   next reference in queue (or this if last)
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
    97
     *    Inactive:   this
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
    98
     */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    Reference next;
10895
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
   100
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
   101
    /* When active:   next element in a discovered reference list maintained by GC (or this if last)
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
   102
     *     pending:   next element in the pending list (or null if last)
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
   103
     *   otherwise:   NULL
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
   104
     */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    transient private Reference<T> discovered;  /* used by VM */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    /* Object used to synchronize with the garbage collector.  The collector
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * must acquire this lock at the beginning of each collection cycle.  It is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * therefore critical that any code holding this lock complete as quickly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * as possible, allocate no new objects, and avoid calling user code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    static private class Lock { };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    private static Lock lock = new Lock();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    /* List of References waiting to be enqueued.  The collector adds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * References to this list, while the Reference-handler thread removes
10895
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
   119
     * them.  This list is protected by the above lock object. The
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
   120
     * list uses the discovered field to link its elements.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    private static Reference pending = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    /* High-priority thread to enqueue pending References
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    private static class ReferenceHandler extends Thread {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        ReferenceHandler(ThreadGroup g, String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            super(g, name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            for (;;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
                Reference r;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
                synchronized (lock) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                    if (pending != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                        r = pending;
10895
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
   138
                        pending = r.discovered;
7434064aba55 4243978: (ref) Race condition in Reference.enqueue()
ysr
parents: 5506
diff changeset
   139
                        r.discovered = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                    } else {
17716
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   141
                        // The waiting on the lock may cause an OOME because it may try to allocate
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   142
                        // exception objects, so also catch OOME here to avoid silent exit of the
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   143
                        // reference handler thread.
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   144
                        //
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   145
                        // Explicitly define the order of the two exceptions we catch here
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   146
                        // when waiting for the lock.
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   147
                        //
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   148
                        // We do not want to try to potentially load the InterruptedException class
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   149
                        // (which would be done if this was its first use, and InterruptedException
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   150
                        // were checked first) in this situation.
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   151
                        //
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   152
                        // This may lead to the VM not ever trying to load the InterruptedException
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   153
                        // class again.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                        try {
17716
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   155
                            try {
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   156
                                lock.wait();
f9486b530c80 7038914: VM could throw uncaught OOME in ReferenceHandler thread
plevart
parents: 14342
diff changeset
   157
                            } catch (OutOfMemoryError x) { }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
                        } catch (InterruptedException x) { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
                        continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                // Fast path for cleaners
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
                if (r instanceof Cleaner) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                    ((Cleaner)r).clean();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
                ReferenceQueue q = r.queue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
                if (q != ReferenceQueue.NULL) q.enqueue(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        ThreadGroup tg = Thread.currentThread().getThreadGroup();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        for (ThreadGroup tgn = tg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
             tgn != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
             tg = tgn, tgn = tg.getParent());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        Thread handler = new ReferenceHandler(tg, "Reference Handler");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        /* If there were a special system-only priority greater than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
         * MAX_PRIORITY, it would be used here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        handler.setPriority(Thread.MAX_PRIORITY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        handler.setDaemon(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        handler.start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    /* -- Referent accessor and setters -- */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     * Returns this reference object's referent.  If this reference object has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     * been cleared, either by the program or by the garbage collector, then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     * this method returns <code>null</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     * @return   The object to which this reference refers, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     *           <code>null</code> if this reference object has been cleared
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    public T get() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        return this.referent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
     * Clears this reference object.  Invoking this method will not cause this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     * object to be enqueued.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     * <p> This method is invoked only by Java code; when the garbage collector
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     * clears references it does so directly, without invoking this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    public void clear() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        this.referent = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    /* -- Queue operations -- */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
     * Tells whether or not this reference object has been enqueued, either by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
     * the program or by the garbage collector.  If this reference object was
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     * not registered with a queue when it was created, then this method will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
     * always return <code>false</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     * @return   <code>true</code> if and only if this reference object has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     *           been enqueued
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    public boolean isEnqueued() {
18815
5da35ed47cfa 8014890: (ref) Reference queues may return more entries than expected
mchung
parents: 17716
diff changeset
   228
        return (this.queue == ReferenceQueue.ENQUEUED);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     * Adds this reference object to the queue with which it is registered,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     * if any.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
     * <p> This method is invoked only by Java code; when the garbage collector
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     * enqueues references it does so directly, without invoking this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * @return   <code>true</code> if this reference object was successfully
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     *           enqueued; <code>false</code> if it was already enqueued or if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     *           it was not registered with a queue when it was created
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    public boolean enqueue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        return this.queue.enqueue(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    /* -- Constructors -- */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    Reference(T referent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        this(referent, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    Reference(T referent, ReferenceQueue<? super T> queue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        this.referent = referent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
}