📄 fifoqueue.java
字号:
/**
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain copyright
* statements and notices. Redistributions must also contain a
* copy of this document.
*
* 2. Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. The name "Exolab" must not be used to endorse or promote
* products derived from this Software without prior written
* permission of Exoffice Technologies. For written permission,
* please contact info@exolab.org.
*
* 4. Products derived from this Software may not be called "Exolab"
* nor may "Exolab" appear in their names without prior written
* permission of Exoffice Technologies. Exolab is a registered
* trademark of Exoffice Technologies.
*
* 5. Due credit should be given to the Exolab Project
* (http://www.exolab.org/).
*
* THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2000-2004 (C) Exoffice Technologies Inc. All Rights Reserved.
*
* $Id: FifoQueue.java,v 1.1 2004/11/26 01:50:35 tanderson Exp $
*/
package org.exolab.jms.common.util;
/**
* This is a very simple implementation of a FIFO queue. The queue only
* holds object types, and is created with a fixed size, and will NOT grow
* during its life. The queue is thread safe.
*
* <P>Items can be added or removed to and from the queue either one at a time
* or in bulk. When the queue is full any attempt to add another object will
* block until the queue has space for it. Any attempt to get an object
* from an empty queue will block until at least one item has been added.
*
* <P>Clients can check to see if the queue is full or empty with available
* helper methods.
*
* <P>When objects are added or removed from the queue, a notify all is called
* to wake any sleeping threads waiting on a queue resource.
*
* @version $Revision: 1.1 $ $Date: 2004/11/26 01:50:35 $
* @author <a href="mailto:mourikis@exolab.org">Jim Mourikis</a>
*/
public class FifoQueue {
/**
* An array is used to hold our objects, for performance.
*/
private Object[] _queue;
/**
* The max number of elements the queue can hold
*/
private final int _capacity;
/**
* The actual number of elements in the queue.
*/
private int _size;
/**
* The start of the queue.
*/
private int _head;
/**
* The end of the queue.
*/
private int _tail;
/**
* The queue constructor. Can only be created with a maximum capacity.
* An empty queue is initially created.
*
* @param capacity the total number of elements this queue is allowed to
* hold
*/
public FifoQueue(int capacity) {
_capacity = (capacity > 0) ? capacity : 1; // at least 1
_queue = new Object[_capacity];
_head = 0;
_tail = 0;
_size = 0;
}
/**
* Get the queues max capacity.
*
* @return the queues max capacity.
*/
public int getCapacity() {
return _capacity;
}
/**
* Get the number of elements the queue currently holds
*
* @return the number of elements in the queue
*/
public synchronized int getSize() {
return _size;
}
/**
* Determines if the queue is empty
*
* @return <code>true</code> if the queue is empty
*/
public synchronized boolean isEmpty() {
return (_size == 0);
}
/**
* Determines if the queue is full
*
* @return <code>true</code> if the queue is full
*/
public synchronized boolean isFull() {
return (_size == _capacity);
}
/**
* Add a new object to the head of the queue. And inform any waiting
* threads.
* No checks are performed for duplicates.
* This call will block if the queue is full, until space is available.
*
* @param obj the new object to add to the queue.
* @throws InterruptedException if interrupted while waiting
*/
public synchronized void add(Object obj) throws InterruptedException {
waitWhileFull();
_queue[_head] = obj;
_head = (_head + 1) % _capacity;
_size++;
notifyAll();
}
/**
* Add a new list of objects to the head of the queue. And inform any
* waiting threads.
* No checks are performed for duplicates.
* This call will block if the queue is full, until space is available.
*
* @param list the list of objects to add to the queue.
* @throws InterruptedException if interrupted while waiting
*/
public synchronized void add(Object[] list) throws InterruptedException {
// todo.
// This could be done more efficiently as an array copy, but can only
// copy as many elements as can fit at a time.
for (int i = 0; i < list.length; i++) {
add(list[i]);
}
}
/**
* Remove and return the object at the end of the queue. Notify any
* waiting threads, once an object has been removed.
* If the queue is currently empty this call will block until
* an item is added.
*
* @return the object at the end of the queue
* @throws InterruptedException if interrupted while waiting
*/
public synchronized Object get() throws InterruptedException {
waitWhileEmpty();
Object obj = _queue[_tail];
// remove our reference.
_queue[_tail] = null;
_tail = (_tail + 1) % _capacity;
_size--;
notifyAll();
return obj;
}
/**
* Remove and return all the objects in the queue in the order they
* were added. Notify any waiting threads, once an object has been removed.
* If the queue is currently empty this call will block until
* an item is added.
*
* <P>If the queue is empty an empty list is returned.
*
* @return all objects in the queue
* @throws InterruptedException if interrupted while waiting
*/
public synchronized Object[] getAll() throws InterruptedException {
Object[] list = new Object[_size];
for (int i = 0; i < list.length; i++) {
list[i] = get();
}
return list;
}
/**
* Wait until timeout if the queue is empty. If timteout is 0
* this call will block until an item is inserted into the queue.
* If there are items in the queue this call will return imediately.
* The return value is true if there are items available in the queue
* else false is return if the timeout was exceeded.
*
* <P>Note: when there are multiple threads waiting on a queue
* there is no guarantee which one will succeed first.
*
* @param timeout the time to wait for in ms.
* @return <code>true</code> if the queue is empty
* @throws InterruptedException if interrupted while waiting
*/
public synchronized boolean waitUntilEmpty(long timeout)
throws InterruptedException {
if (timeout == 0L) {
waitUntilEmpty();
return true;
}
// wait only for the specified amount of time
long endTime = System.currentTimeMillis() + timeout;
long remaining = timeout;
while (!isEmpty() && (remaining > 0L)) {
wait(remaining);
remaining = endTime - System.currentTimeMillis();
}
return isEmpty();
}
/**
* Wait until the queue becomes empty.
*
* @throws InterruptedException if interrupted while waiting
*/
public synchronized void waitUntilEmpty() throws InterruptedException {
while (!isEmpty()) {
wait();
}
}
/**
* Wait while the queue is empty.
*
* @throws InterruptedException if interrupted while waiting
*/
public synchronized void waitWhileEmpty() throws InterruptedException {
while (isEmpty()) {
wait();
}
}
/**
* Wait until the queue becomes full.
*
* @throws InterruptedException if interrupted while waiting
*/
public synchronized void waitUntilFull() throws InterruptedException {
while (!isFull()) {
wait();
}
}
/**
* Wait while the queue is full.
*
* @throws InterruptedException if interrupted while waiting
*/
public synchronized void waitWhileFull() throws InterruptedException {
while (isFull()) {
wait();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -