/**
* A blocking queue which wraps {@code ArrayBlockingQueue}, and with the
* following features.
* <li>Use null object as end of queue.
* <li>Supports muti-producers for the queue. Only if all the producers put a position-pill to
* the queue, the queue will reach end of life.
*
* @param <T>
* element type
*/
public class Queue<T> {
private ArrayBlockingQueue<Element<T>> queue = null;
private AtomicInteger lifeValue ;
private static int DEFAULT_LIFE_VALUE = 1;
/**
*
* @param capacity The queue size
* @param lifeValue It is set as the number of producer of the queue as a rule
*/
public Queue(int capacity, int lifeValue) {
this.queue = new ArrayBlockingQueue<Element<T>>(capacity);
this.lifeValue = new AtomicInteger(lifeValue);
}
public Queue(int capacity) {
this( capacity, DEFAULT_LIFE_VALUE );
}
/**
* Put an position-pill to the queue.
* @throws InterruptedException
*/
@SuppressWarnings("unchecked")
public void putEnd() throws InterruptedException{
int life = this.lifeValue.decrementAndGet();
if(life <= 0 ){
this.queue.put(Element.NULL);
}
}
/**
* Put an element to the queue
* @param element
* @throws InterruptedException
*/
public void put(T element ) throws InterruptedException{
try {
queue.put(new Element<T>(element));
} catch (InterruptedException e) {
this.queue.clear();
throw e;
}
}
/**
* Take an element from the head of queue.
* If queue is empty, the operation will be blocked.
*
* @return a non-nullable object if queue if not empty, or null if the queue is ended
* @throws InterruptedException
*/
public T take() throws InterruptedException{
Element<T> element = this.queue.take();
if( Element.NULL == element){
this.queue.put(Element.NULL);
}
return element.getObject();
}
/**
* Take elements in batch from the queue. The operation will be blocked for a non-ended queue.
* The fetched list size should be equal to count unless the queue is ended
* @param count the desired element size to fetch
* @return a List which contains the batch fetched element, or null if the queue is ended and empty
* @throws InterruptedException
*/
public List<T> batchTake(int count) throws InterruptedExcept