Created
May 7, 2014 23:20
-
-
Save ecolban/21ac0fd081f3ea167cfe to your computer and use it in GitHub Desktop.
How to iterate over a BlockingQueue.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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