egerardus
egerardus

Reputation: 11486

Get the capacity of an ArrayBlockingQueue

I need to shrink an ArrayBlockingQueue capacity by 1.

I was thinking nothing should be easier:

  1. Get the capacity of the current queue.
  2. Create a new queue with capacity - 1
  3. Use the BlockingQueue.drainTo function to move over any elements in the old queue to the new queue.
  4. Take the rest of the day off...

However, I am thoroughly bugged at step 1. For some inconceivable reason ArrayBlockingQueue does not expose the capacity. I can think of no reason for this to be private, it is a bounded queue and offers the getRemainingCapacity method, why can I not get the capacity?

I cannot do size() + getRemainingCapacity() because this is a concurrent queue, there is always the possibility of something changing the queue in between the size and getRemainingCapacity calls.

Surely I am not the first person to need a capacity for an ArrayBlockingQueue. Short of extending the whole class to add a getCapacity method, or creating a separate structure to map the capacity of my queues, is there a simple solution for this?

Or maybe an intelligent reason why the capacity should not be known? (aside from an oversight)

More background: My multi-threaded program uses many queues, it calls the BlockingQueue.getRemainingCapacity function to know when a queue is full and then process it from there. In a rare corner case the program discovers that the queue capacity is 1 element too large partway through filling it up. I need to reduce the size of the queue by 1 otherwise it will never fill up and never get processed.

Upvotes: 1

Views: 1280

Answers (1)

egerardus
egerardus

Reputation: 11486

For now, I am going with this...

import java.util.concurrent.ArrayBlockingQueue;

@SuppressWarnings("serial")
public class InformativeBlockingQueue<E> extends ArrayBlockingQueue<E>
{
    private final int visibleCapacity;
    
    public InformativeBlockingQueue(int capacity)
    {
        super(capacity, false);
        this.capacity = capacity;
    }

    public InformativeBlockingQueue(int capacity, boolean fair)
    {
        super(capacity, fair);
        this.visibleCapacity = capacity;
    }
    
    public int getCapacity()
    {
        return visibleCapacity;
    }
}

I feel like it should not require an extension just to get the capacity though.

Upvotes: 3

Related Questions