org.jgroups.util.Queue Maven / Gradle / Ivy
Go to download
This artifact provides a single jar that contains all classes required to use remote Jakarta Enterprise Beans and Jakarta Messaging, including
all dependencies. It is intended for use by those not using maven, maven users should just import the Jakarta Enterprise Beans and
Jakarta Messaging BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up
with different versions on classes on the class path).
package org.jgroups.util;
import org.jgroups.logging.Log;
import org.jgroups.logging.LogFactory;
import org.jgroups.TimeoutException;
import java.util.*;
/**
* 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)
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)
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
© 2015 - 2025 Weber Informatics LLC | Privacy Policy