java BlockingQueue does not have a blocking peek?

Viewed 13681

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.

8 Answers

Not an answer per se, but: JDK-6653412 claims this is not a valid use case.

The 'simplest' solution

Do not process the next element until the previous element is processed succesfully.

public void run() {

Object lastSuccessfullyProcessedElement = null;

    while (!exit) {
        Object obj =  lastSuccessfullyProcessedElement == null ? queue.take() : lastSuccessfullyProcessedElement; // blocking
        
        boolean successful = process(obj);
        
        if(!successful) {
            lastSuccessfullyProcessedElement = obj;
        } else {
            lastSuccessfullyProcessedElement = null;
        }
    }
}
  1. Calling peek() and checking if the value is null is not CPU efficient.

I have seen CPU usage going to 10% on my system when the queue is empty for the following program.

while (true) {
   Object o = queue.peek();
   if(o == null) continue;
   // omitted for the sake of brevity
}
  1. Adding sleep() adds slowness.

  2. Adding it back to the queue using putLast will disturb the order. Moreover, it is a blocking operation which requires locks.

Related