Search code examples
javablockingqueue

A bounded BlockingQueue that doesn't block


The title of this question makes me doubt if this exist, but still:

I'm interested in whether there is an implemented of Java's BlockingQueue, that is bounded by size, and never blocks, but rather throws an exception when trying to enqueue too many elements.

Edit - I'm passing the BlockingQueue to an Executor, which I suppose uses its add() method, not offer(). One can write a BlockingQueue that wraps another BlockingQueue and delegates calls to add() to offer().


Solution

  • Edit: Based on your new description I believe that you're asking the wrong question. If you're using a Executor you should probably define a custom RejectedExecutionHandler rather than modifying the queue. This only works if you're using a ThreadPoolExecutor, but if you're not it would probably be a better idea to modify the Executor rather than the queue.

    It's my opinion that it's a mistake to override offer and make it behave like add. Interface methods constitute a contract. Client code that uses blocking queues depends on the methods actually doing what the documentation specifies. Breaking that rule opens up for a world of hurt. That, And it's inelegant.


    The add() method on BlockingQueues does that, but they also have an offer() method which is generally a better choice. From the documentation for offer():

    Inserts the specified element at the tail of this queue if it is possible to do so immediately without exceeding the queue's capacity, returning true upon success and false if this queue is full. This method is generally preferable to method add(E), which can fail to insert an element only by throwing an exception.

    This works for all such queues regardless of the specific implementation (ArrayBlockingQueue, LinkedBlockingQueue etc.)

    BlockingQueue<String> q = new LinkedBlockingQueue<String>(2);
    System.out.println(q.offer("foo")); // true
    System.out.println(q.offer("bar")); // true
    System.out.println(q.offer("baz")); // false