Does polling block other operations in LinkedBlockingQueue?

fibera picture fibera · May 14, 2012 · Viewed 10.1k times · Source

In the pseudocode below I have a poll() function that gets called forever in the main thread. When I do this without the sleep() statement in poll(), only 2-3 items a minute get added to the queue by the other thread. Does this mean that polling blocks the put() statement?

How can I solve this problem?

public class Test extends Thread{
    private LinkedBlockingQueue<Object> queue = null;

    Test(){
        queue = new LinkedBlockingQueue<Object>(10);
    }

    public void run(){
        // Do stuff, get incoming object from network
        queue.put(o);
    }

    public Object poll(){
        Object o = queue.poll();
        sleep(1000);
        return o;
    }
}

Answer

Gray picture Gray · May 14, 2012

Does this mean that polling blocks the put() statement?

No, LinkedBlockingQueue is fully reentrant and the poll() method does not block the put(). However, the poll() method returns immediately. You probably should be using queue.take() which waits for there to be an item in the queue instead of returning null if the queue is empty.

// wait for there to be an object in the queue
Object o = queue.take();
// no sleep necessary
return o;

Since you are constructing a constrained blocking queue of 10 entries, I guess that main is blocking on the sleep() and the queue then fills up and slows down your program. You maybe should only sleep if there poll() returns null and sleep for a shorter amount of time.

Edit: As @JohnVint mentioned in the comments, another alternative is to use the poll(long, TimeUnit) method which will wait for an item to be added to the queue for the time period and returns null if the timer expires. That is a cleaner way to wait for something in the queue.

// wait for 1000ms for there to be an object in the queue
Object o = queue.poll(1000, TimeUnit.MILLISECONDS);
// no sleep necessary
return o;