KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > lang > ref > ReferenceQueue


1 /*
2  * @(#)ReferenceQueue.java 1.25 07/06/04
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.lang.ref;
9
10 /**
11  * Reference queues, to which registered reference objects are appended by the
12  * garbage collector after the appropriate reachability changes are detected.
13  *
14  * @version 1.25, 06/04/07
15  * @author Mark Reinhold
16  * @since 1.2
17  */

18
19 public class ReferenceQueue<T> {
20
21     /**
22      * Constructs a new reference-object queue.
23      */

24     public ReferenceQueue() { }
25
26     private static class Null extends ReferenceQueue JavaDoc {
27     boolean enqueue(Reference JavaDoc r) {
28         return false;
29     }
30     }
31
32     static ReferenceQueue JavaDoc NULL = new Null();
33     static ReferenceQueue JavaDoc ENQUEUED = new Null();
34
35     static private class Lock { };
36     private Lock lock = new Lock();
37     private Reference JavaDoc<? extends T> head = null;
38     private long queueLength = 0;
39     private volatile boolean queueEmpty = true;
40
41     boolean enqueue(Reference JavaDoc<? extends T> r) { /* Called only by Reference class */
42     synchronized (r) {
43         if (r.queue == ENQUEUED) return false;
44         synchronized (lock) {
45         r.queue = ENQUEUED;
46         r.next = (head == null) ? r : head;
47         head = r;
48         queueLength++;
49         if (queueEmpty) queueEmpty = false;
50                 if (r instanceof FinalReference JavaDoc) {
51                     sun.misc.VM.addFinalRefCount(1);
52                 }
53         lock.notifyAll();
54         return true;
55         }
56     }
57     }
58
59     private Reference JavaDoc<? extends T> reallyPoll() { /* Must hold lock */
60     if (head != null) {
61         Reference JavaDoc<? extends T> r = head;
62         head = (r.next == r) ? null : r.next;
63         r.queue = NULL;
64         r.next = r;
65         queueLength--;
66         if (queueLength <= 0) queueEmpty = true;
67             if (r instanceof FinalReference JavaDoc) {
68                 sun.misc.VM.addFinalRefCount(-1);
69             }
70         return r;
71     }
72     return null;
73     }
74
75     /**
76      * Polls this queue to see if a reference object is available. If one is
77      * available without further delay then it is removed from the queue and
78      * returned. Otherwise this method immediately returns <tt>null</tt>.
79      *
80      * @return A reference object, if one was immediately available,
81      * otherwise <code>null</code>
82      */

83     public Reference JavaDoc<? extends T> poll() {
84     if(queueEmpty) return null;
85     synchronized (lock) {
86         return reallyPoll();
87     }
88     }
89
90     /**
91      * Removes the next reference object in this queue, blocking until either
92      * one becomes available or the given timeout period expires.
93      *
94      * <p> This method does not offer real-time guarantees: It schedules the
95      * timeout as if by invoking the {@link Object#wait(long)} method.
96      *
97      * @param timeout If positive, block for up <code>timeout</code>
98      * milliseconds while waiting for a reference to be
99      * added to this queue. If zero, block indefinitely.
100      *
101      * @return A reference object, if one was available within the specified
102      * timeout period, otherwise <code>null</code>
103      *
104      * @throws IllegalArgumentException
105      * If the value of the timeout argument is negative
106      *
107      * @throws InterruptedException
108      * If the timeout wait is interrupted
109      */

110     public Reference JavaDoc<? extends T> remove(long timeout)
111     throws IllegalArgumentException JavaDoc, InterruptedException JavaDoc
112     {
113     if (timeout < 0) {
114         throw new IllegalArgumentException JavaDoc("Negative timeout value");
115     }
116     synchronized (lock) {
117         Reference JavaDoc<? extends T> r = reallyPoll();
118         if (r != null) return r;
119         for (;;) {
120         lock.wait(timeout);
121         r = reallyPoll();
122         if (r != null) return r;
123         if (timeout != 0) return null;
124         }
125     }
126     }
127
128     /**
129      * Removes the next reference object in this queue, blocking until one
130      * becomes available.
131      *
132      * @return A reference object, blocking until one becomes available
133      * @throws InterruptedException If the wait is interrupted
134      */

135     public Reference JavaDoc<? extends T> remove() throws InterruptedException JavaDoc {
136     return remove(0);
137     }
138
139 }
140
Popular Tags