java BlockingQueue does not have a blocking peek?

rouble picture rouble · Nov 19, 2009 · Viewed 11.7k times · Source

I have a blocking queue of objects.

I want to write a thread that blocks till there is a object on the queue. Similar to the functionality provided by BlockingQueue.take().

However, since I do not know if I will be able to process the object successfully, I want to just peek() and not remove the object. I want to remove the object only if I am able to process it successfully.

So, I would like a blocking peek() function. Currently, peek() just returns if the queue is empty as per the javadocs.

Am I missing something? Is there another way to achieve this functionality?

EDIT:

Any thoughts on if I just used a thread safe queue and peeked and slept instead?

public void run() {
    while (!exit) {
        while (queue.size() != 0) {
            Object o =  queue.peek();
            if (o != null) {
                if (consume(o) == true) {
                    queue.remove();
                } else {
                    Thread.sleep(10000); //need to backoff (60s) and try again
                }
            }
        }
        Thread.sleep(1000); //wait 1s for object on queue
    }
}

Note that I only have one consumer thread and one (separate) producer thread. I guess this isn't as efficient as using a BlockingQueue... Any comments appreciated.

Answer

Adamski picture Adamski · Nov 19, 2009

You could use a LinkedBlockingDeque and physically remove the item from the queue (using takeLast()) but replace it again at the end of the queue if processing fails using putLast(E e). Meanwhile your "producers" would add elements to the front of the queue using putFirst(E e).

You could always encapsulate this behaviour within your own Queue implementation and provide a blockingPeek() method that performs takeLast() followed by putLast() behind the scenes on the underlying LinkedBlockingDeque. Hence from the calling client's perspective the element is never removed from your queue.