/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.util;
import java.util.ArrayList;
/**
* @author epr
*/
public class Queue<T> {
public static final int NO_WAIT = -1;
/**
* The actual queue
*/
private final ArrayList<T> queue = new ArrayList<T>();
private boolean closed = false;
/**
* Gets the first element out of the queue. Blocks until an element is available
* and the returns element is remove from the queue.
*
* @param ignoreInteruptions If true, InterruptedException's are ignore, otherwise
* and InterruptedException results in a return of <code>null</code>.
* @param timeout to wait for an object in the queue. On timeout, null is returned.
* A value of 0 means wait for ever.
* @return Object The first object in the queue, or null if the queue has
* been closed, a timeout occurs, or the current thread is interrupted (and ignoreInterruptions is false).
*/
public synchronized T get(boolean ignoreInteruptions, long timeout) {
while (queue.isEmpty()) {
if (closed || timeout == NO_WAIT) {
return null;
}
try {
wait(timeout);
} catch (InterruptedException ex) {
if (!ignoreInteruptions) {
return null;
}
/* ignore */
}
if ((timeout != 0) && (queue.isEmpty())) {
return null;
}
}
return queue.remove(0);
}
/**
* Gets the first element out of the queue. Blocks until an element is available
* and the returns element is remove from the queue.
*
* @param timeout to wait for an object in the queue. On timeout, null is returned.
* A value of 0 means wait for ever.
* @return Object The first object in the queue, or null if the queue has
* been closed, or a timeout occurs.
*/
public T get(long timeout) {
return get(true, timeout);
}
/**
* Gets the first element out of the queue. Blocks until an element is available
* and the returns element is remove from the queue.
*
* @param ignoreInteruptions If true, InterruptedException's are ignore, otherwise
* and InterruptedException results in a return of <code>null</code>.
* @return Object The first object in the queue, or null if the queue has
* been closed, or the current thread is interrupted (and ignoreInterruptions is false).
*/
public T get(boolean ignoreInteruptions) {
return get(ignoreInteruptions, 0);
}
/**
* Gets the first element out of the queue. Blocks until an element is available
* and the returns element is remove from the queue.
*
* @return Object
*/
public T get() {
return get(true, 0);
}
/**
* Add an element to this queue.
*
* @param object
* @throws SecurityException If the queue has been closed.
*/
public synchronized void add(T object)
throws SecurityException {
if (closed) {
throw new SecurityException("Cannot add to a closed queue.");
} else {
queue.add(object);
notifyAll();
}
}
/**
* Remove an element from this queue.
*
* @param object
* @throws SecurityException If the queue has been closed.
*/
public synchronized void remove(T object)
throws SecurityException {
if (closed) {
throw new SecurityException("Cannot remove from a closed queue.");
} else {
queue.remove(object);
notifyAll();
}
}
/**
* Does this queue contain a given object?
*
* @param object
* @return boolean
*/
public boolean contains(T object) {
return queue.contains(object);
}
/**
* Gets the number of elements in this queue.
*
* @return int
*/
public int size() {
return queue.size();
}
/**
* Is this queue empty.
*
* @return boolean
*/
public boolean isEmpty() {
return queue.isEmpty();
}
/**
* Close this queue. All thread blocks in the <code>get</code> method
* will return with a null value.
*/
public synchronized void close() {
this.closed = true;
notifyAll();
}
/**
* Is this queue closed.
* @return {@code true} if the queue is closed, {@code false} otherwise.
*/
public boolean isClosed() {
return closed;
}
}