Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
// $Id: Queue.java,v 1.34 2009/08/18 11:52:14 belaban Exp $
package bboss.org.jgroups.util;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import bboss.org.jgroups.TimeoutException;
import bboss.org.jgroups.logging.Log;
import bboss.org.jgroups.logging.LogFactory;
/**
* Elements are added at the tail and removed from the head. Class is thread-safe in that
* 1 producer and 1 consumer may add/remove elements concurrently. The class is not
* explicitely designed for multiple producers or consumers. Implemented as a linked
* list, so that removal of an element at the head does not cause a right-shift of the
* remaining elements (as in a Vector-based implementation).
* @author Bela Ban
*/
public class Queue {
/*head and the tail of the list so that we can easily add and remove objects*/
private Element head=null, tail=null;
/*flag to determine the state of the queue*/
private volatile boolean closed=false;
/*current size of the queue*/
private volatile int size=0;
/* Lock object for synchronization. Is notified when element is added */
private final Object mutex=new Object();
/** Lock object for syncing on removes. It is notified when an object is removed */
// Object remove_mutex=new Object();
/*the number of end markers that have been added*/
private int num_markers=0;
/**
* if the queue closes during the runtime
* an endMarker object is added to the end of the queue to indicate that
* the queue will close automatically when the end marker is encountered
* This allows for a "soft" close.
* @see Queue#close
*/
private static final Object endMarker=new Object();
protected static final Log log=LogFactory.getLog(Queue.class);
/**
* the class Element indicates an object in the queue.
* This element allows for the linked list algorithm by always holding a
* reference to the next element in the list.
* if Element.next is null, then this element is the tail of the list.
*/
static class Element {
/*the actual value stored in the queue*/
Object obj=null;
/*pointer to the next item in the (queue) linked list*/
Element next=null;
/**
* creates an Element object holding its value
* @param o - the object to be stored in the queue position
*/
Element(Object o) {
obj=o;
}
/**
* prints out the value of the object
*/
public String toString() {
return obj != null? obj.toString() : "null";
}
}
/**
* creates an empty queue
*/
public Queue() {
}
/**
* Returns the first element. Returns null if no elements are available.
*/
public Object getFirst() {
synchronized(mutex) {
return head != null? head.obj : null;
}
}
/**
* Returns the last element. Returns null if no elements are available.
*/
public Object getLast() {
synchronized(mutex) {
return tail != null? tail.obj : null;
}
}
/**
* returns true if the Queue has been closed
* however, this method will return false if the queue has been closed
* using the close(true) method and the last element has yet not been received.
* @return true if the queue has been closed
*/
public boolean closed() {
synchronized(mutex) {
return closed;
}
}
/**
* adds an object to the tail of this queue
* If the queue has been closed with close(true) no exception will be
* thrown if the queue has not been flushed yet.
* @param obj - the object to be added to the queue
* @exception QueueClosedException exception if closed() returns true
*/
public void add(Object obj) throws QueueClosedException {
if(obj == null) {
if(log.isErrorEnabled()) log.error("argument must not be null");
return;
}
/*lock the queue from other threads*/
synchronized(mutex) {
if(closed)
throw new QueueClosedException();
if(this.num_markers > 0)
throw new QueueClosedException("queue has been closed. You can not add more elements. " +
"Waiting for removal of remaining elements.");
addInternal(obj);
/*wake up all the threads that are waiting for the lock to be released*/
mutex.notifyAll();
}
}
public void addAll(Collection c) throws QueueClosedException {
if(c == null) {
if(log.isErrorEnabled()) log.error("argument must not be null");
return;
}
/*lock the queue from other threads*/
synchronized(mutex) {
if(closed)
throw new QueueClosedException();
if(this.num_markers > 0)
throw new QueueClosedException("queue has been closed. You can not add more elements. " +
"Waiting for removal of remaining elements.");
Object obj;
for(Iterator it=c.iterator(); it.hasNext();) {
obj=it.next();
if(obj != null)
addInternal(obj);
}
/*wake up all the threads that are waiting for the lock to be released*/
mutex.notifyAll();
}
}
public void addAll(List