Skip to content

Instantly share code, notes, and snippets.

@ecolban
Created May 7, 2014 23:20
Show Gist options
  • Save ecolban/21ac0fd081f3ea167cfe to your computer and use it in GitHub Desktop.
Save ecolban/21ac0fd081f3ea167cfe to your computer and use it in GitHub Desktop.
How to iterate over a BlockingQueue.
/**
* A BlockingQueue comes with an iterator() method which is more or less unusable because its hasNext()
* method may return false before the last element has been placed on the queue. To indicate that the last
* element has been put on the queue, we use the same trick used at some airports to indicate that the last
* piece of baggage has been placed on the baggage conveyor belt: A red suitcase marks the end.
*/
public class MyClass implements Iterable<String> {
private BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
private String redSuitcase;
/**
* Add stuff to the queue. This method could be invoked from a separate 'producer' thread.
*/
public void run() {
//... Add stuff
//...
if(<last element on queue>) {
queue.put(redSuitcase = new String("EOQ")); //We purposely create a *new* object to
// make sure that it is different from any
// other object on the queue which might
// coincidently be equal to "EOQ" (yet != redSuitcase).
}
}
/**
* Gets an iterator
*/
@Override
public Iterator<String> iterator() {
return new Iterator<String>() {
String next = null;
boolean consumed = true;
@Override
public boolean hasNext() {
if (consumed) {
try {
next = queue.take();
consumed = false;
} catch (InterruptedException e) {
return false;
}
}
return redSuitcase == null || next != redSuitcase; // We purposely avoid using String.equal()
}
@Override
public String next() {
if (consumed) {
try {
next = timeStepQueue.take();
consumed = false;
} catch (InterruptedException e) {
throw new NoSuchElementException();
}
}
if (redSuitcase == null || next != redSuitcase) { // We purposely avoid using String.equal()
consumed = true;
return next;
} else {
throw new NoSuchElementException();
}
}
@Override
public void remove() {
// Not implemented
}
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment