Skip to content

Instantly share code, notes, and snippets.

@ratamacue
Created July 21, 2016 20:30
Show Gist options
  • Save ratamacue/74e1b77a2fcfe8e829746831ab9e7e06 to your computer and use it in GitHub Desktop.
Save ratamacue/74e1b77a2fcfe8e829746831ab9e7e06 to your computer and use it in GitHub Desktop.
package cj.util.collections;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* @author dron
* This class should be used as an "iterable" by consumers and a queue by producers.
* Unlike a normal blocking queue, the iterator will BLOCK on hasNext rather than returning false
* which allows this type to work like a buffer.
*
* Multiple calls to iterator() will return different iterators with the same thread-safe backing data
* Which would allow multiple consumer threads to share the work generated by any number of producers adding to this queue.
*
* Consumers will continue to iterate until producers call the "done()" method.
*
*/
public class IterableBlockingQueue<T> implements Iterable<T>{
private Queue<T> queue = new ConcurrentLinkedQueue<T>();
private boolean isDone=false;
public void done(){
isDone=true;
}
public void add(T object){
queue.add(object);
}
public Integer size() {
return queue.size();
}
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
@Override
public boolean hasNext() {
try {
//TODO: Waiting 300ms is a naive solution to blocking.
while(queue.isEmpty() && !isDone) Thread.sleep(300);
} catch (InterruptedException e) {}
return !(queue.isEmpty() && isDone);
}
@Override
public T next() {
return queue.remove();
}
@Override
public void remove() {
queue.remove();
}
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment