KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > exolab > jms > common > util > FifoQueue


1 /**
2  * Redistribution and use of this software and associated documentation
3  * ("Software"), with or without modification, are permitted provided
4  * that the following conditions are met:
5  *
6  * 1. Redistributions of source code must retain copyright
7  * statements and notices. Redistributions must also contain a
8  * copy of this document.
9  *
10  * 2. Redistributions in binary form must reproduce the
11  * above copyright notice, this list of conditions and the
12  * following disclaimer in the documentation and/or other
13  * materials provided with the distribution.
14  *
15  * 3. The name "Exolab" must not be used to endorse or promote
16  * products derived from this Software without prior written
17  * permission of Exoffice Technologies. For written permission,
18  * please contact info@exolab.org.
19  *
20  * 4. Products derived from this Software may not be called "Exolab"
21  * nor may "Exolab" appear in their names without prior written
22  * permission of Exoffice Technologies. Exolab is a registered
23  * trademark of Exoffice Technologies.
24  *
25  * 5. Due credit should be given to the Exolab Project
26  * (http://www.exolab.org/).
27  *
28  * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32  * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39  * OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  * Copyright 2000-2004 (C) Exoffice Technologies Inc. All Rights Reserved.
42  *
43  * $Id: FifoQueue.java,v 1.1 2004/11/26 01:50:35 tanderson Exp $
44  */

45 package org.exolab.jms.common.util;
46
47
48 /**
49  * This is a very simple implementation of a FIFO queue. The queue only
50  * holds object types, and is created with a fixed size, and will NOT grow
51  * during its life. The queue is thread safe.
52  *
53  * <P>Items can be added or removed to and from the queue either one at a time
54  * or in bulk. When the queue is full any attempt to add another object will
55  * block until the queue has space for it. Any attempt to get an object
56  * from an empty queue will block until at least one item has been added.
57  *
58  * <P>Clients can check to see if the queue is full or empty with available
59  * helper methods.
60  *
61  * <P>When objects are added or removed from the queue, a notify all is called
62  * to wake any sleeping threads waiting on a queue resource.
63  *
64  * @version $Revision: 1.1 $ $Date: 2004/11/26 01:50:35 $
65  * @author <a HREF="mailto:mourikis@exolab.org">Jim Mourikis</a>
66  */

67 public class FifoQueue {
68
69     /**
70      * An array is used to hold our objects, for performance.
71      */

72     private Object JavaDoc[] _queue;
73
74     /**
75      * The max number of elements the queue can hold
76      */

77     private final int _capacity;
78
79     /**
80      * The actual number of elements in the queue.
81      */

82     private int _size;
83
84     /**
85      * The start of the queue.
86      */

87     private int _head;
88
89     /**
90      * The end of the queue.
91      */

92     private int _tail;
93
94     /**
95      * The queue constructor. Can only be created with a maximum capacity.
96      * An empty queue is initially created.
97      *
98      * @param capacity the total number of elements this queue is allowed to
99      * hold
100      */

101     public FifoQueue(int capacity) {
102         _capacity = (capacity > 0) ? capacity : 1; // at least 1
103
_queue = new Object JavaDoc[_capacity];
104         _head = 0;
105         _tail = 0;
106         _size = 0;
107     }
108
109     /**
110      * Get the queues max capacity.
111      *
112      * @return the queues max capacity.
113      */

114     public int getCapacity() {
115         return _capacity;
116     }
117
118     /**
119      * Get the number of elements the queue currently holds
120      *
121      * @return the number of elements in the queue
122      */

123     public synchronized int getSize() {
124         return _size;
125     }
126
127     /**
128      * Determines if the queue is empty
129      *
130      * @return <code>true</code> if the queue is empty
131      */

132     public synchronized boolean isEmpty() {
133         return (_size == 0);
134     }
135
136     /**
137      * Determines if the queue is full
138      *
139      * @return <code>true</code> if the queue is full
140      */

141     public synchronized boolean isFull() {
142         return (_size == _capacity);
143     }
144
145     /**
146      * Add a new object to the head of the queue. And inform any waiting
147      * threads.
148      * No checks are performed for duplicates.
149      * This call will block if the queue is full, until space is available.
150      *
151      * @param obj the new object to add to the queue.
152      * @throws InterruptedException if interrupted while waiting
153      */

154     public synchronized void add(Object JavaDoc obj) throws InterruptedException JavaDoc {
155         waitWhileFull();
156
157         _queue[_head] = obj;
158         _head = (_head + 1) % _capacity;
159         _size++;
160         notifyAll();
161     }
162
163     /**
164      * Add a new list of objects to the head of the queue. And inform any
165      * waiting threads.
166      * No checks are performed for duplicates.
167      * This call will block if the queue is full, until space is available.
168      *
169      * @param list the list of objects to add to the queue.
170      * @throws InterruptedException if interrupted while waiting
171      */

172     public synchronized void add(Object JavaDoc[] list) throws InterruptedException JavaDoc {
173         // todo.
174
// This could be done more efficiently as an array copy, but can only
175
// copy as many elements as can fit at a time.
176
for (int i = 0; i < list.length; i++) {
177             add(list[i]);
178         }
179     }
180
181     /**
182      * Remove and return the object at the end of the queue. Notify any
183      * waiting threads, once an object has been removed.
184      * If the queue is currently empty this call will block until
185      * an item is added.
186      *
187      * @return the object at the end of the queue
188      * @throws InterruptedException if interrupted while waiting
189      */

190     public synchronized Object JavaDoc get() throws InterruptedException JavaDoc {
191         waitWhileEmpty();
192
193         Object JavaDoc obj = _queue[_tail];
194
195         // remove our reference.
196
_queue[_tail] = null;
197
198         _tail = (_tail + 1) % _capacity;
199         _size--;
200         notifyAll();
201         return obj;
202     }
203
204     /**
205      * Remove and return all the objects in the queue in the order they
206      * were added. Notify any waiting threads, once an object has been removed.
207      * If the queue is currently empty this call will block until
208      * an item is added.
209      *
210      * <P>If the queue is empty an empty list is returned.
211      *
212      * @return all objects in the queue
213      * @throws InterruptedException if interrupted while waiting
214      */

215     public synchronized Object JavaDoc[] getAll() throws InterruptedException JavaDoc {
216         Object JavaDoc[] list = new Object JavaDoc[_size];
217
218         for (int i = 0; i < list.length; i++) {
219             list[i] = get();
220         }
221         return list;
222     }
223
224     /**
225      * Wait until timeout if the queue is empty. If timteout is 0
226      * this call will block until an item is inserted into the queue.
227      * If there are items in the queue this call will return imediately.
228      * The return value is true if there are items available in the queue
229      * else false is return if the timeout was exceeded.
230      *
231      * <P>Note: when there are multiple threads waiting on a queue
232      * there is no guarantee which one will succeed first.
233      *
234      * @param timeout the time to wait for in ms.
235      * @return <code>true</code> if the queue is empty
236      * @throws InterruptedException if interrupted while waiting
237      */

238     public synchronized boolean waitUntilEmpty(long timeout)
239         throws InterruptedException JavaDoc {
240         if (timeout == 0L) {
241             waitUntilEmpty();
242             return true;
243         }
244
245         // wait only for the specified amount of time
246
long endTime = System.currentTimeMillis() + timeout;
247         long remaining = timeout;
248
249         while (!isEmpty() && (remaining > 0L)) {
250             wait(remaining);
251             remaining = endTime - System.currentTimeMillis();
252         }
253         return isEmpty();
254     }
255
256     /**
257      * Wait until the queue becomes empty.
258      *
259      * @throws InterruptedException if interrupted while waiting
260      */

261     public synchronized void waitUntilEmpty() throws InterruptedException JavaDoc {
262         while (!isEmpty()) {
263             wait();
264         }
265     }
266
267     /**
268      * Wait while the queue is empty.
269      *
270      * @throws InterruptedException if interrupted while waiting
271      */

272     public synchronized void waitWhileEmpty() throws InterruptedException JavaDoc {
273         while (isEmpty()) {
274             wait();
275         }
276     }
277
278     /**
279      * Wait until the queue becomes full.
280      *
281      * @throws InterruptedException if interrupted while waiting
282      */

283     public synchronized void waitUntilFull() throws InterruptedException JavaDoc {
284         while (!isFull()) {
285             wait();
286         }
287     }
288
289     /**
290      * Wait while the queue is full.
291      *
292      * @throws InterruptedException if interrupted while waiting
293      */

294     public synchronized void waitWhileFull() throws InterruptedException JavaDoc {
295         while (isFull()) {
296             wait();
297         }
298     }
299 }
300
Popular Tags