Why does the iterator.hasNext not work with BlockingQueue? Why does the iterator.hasNext not work with BlockingQueue? multithreading multithreading

Why does the iterator.hasNext not work with BlockingQueue?


Just don't use iterators with Queues. Use peek() or poll() instead or take() if it's a BlockingQueue:

void consume() {    new Thread() {        @Override        public void run() {            Object value;            // actually, when using a BlockingQueue,            // take() would be better than poll()            while ((value=q.poll())!=null)                System.out.println(value);        }    }.start();}

A Queue is an Iterable because it is a Collection and hence needs to provide an iterator() method, but that shouldn't ever be used, or you shouldn't be using a Queue in the first place.


1) Is this bad design, or wrong expectation?

Wrong expectations since it would otherwise violate the contract of Iterator which on Iterator.next() says: Throws: NoSuchElementException - iteration has no more elements.If next() would block the exception would never be thrown.

2) Is there a way to use the blocking methods

Yes, for instance by extending the class and overriding the next and hasNext methods to use blocking routines instead. Note that hasNext would need to always return true in this case - which again violates the contract.


if an iterator blocked on hasNext then the iteration would never finish unless you explicitly broke out of it, this would be quite a strange design.

In any case the LinkedBlockingQueue javadoc has this to say

Returns an iterator over the elements in this queue in proper sequence. The returned <tt>Iterator</tt> is a "weakly consistent" iterator that will never throw {@link ConcurrentModificationException}, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.