Your MyArrayBlockingQueue
doesn't override BlockingQueue.offer(E, long, TimeUnit)
or BlockingQueue.poll(long, TImeUnit)
. Do you actually need a queue with "blocking" features? If you do not then you can create a thread-safe queue backed by an EvictingQueue
using Queues.synchronizedQueue(Queue)
:
Queues.synchronizedQueue(EvictingQueue.create(maxSize));
For an evicting blocking queue, I see a few issues with your proposed implementation:
remove()
may throw an exception if the queue is empty. Your offer
method is marked with synchronized
but poll
, remove
, etc. are not so another thread could drain your queue in between calls to size()
and remove()
. I suggest using poll()
instead which won't throw an exception.
- Your call to
offer
may still return false
(i.e. not "add" the element) because of another race condition where between checking the size and/or removing an element to reduce the size a different thread adds an element filling the queue. I recommend using a loop off of the result of offer
until true
is returned (see below).
- Calling
size()
, remove()
and offer(E)
each require a lock so in the worse case scenario your code locks and unlocks 3 times (and even then it might fail to behave as desired due to the previous issues described).
I believe the following implementation will get you what you are after:
public class EvictingBlockingQueue<E> extends ArrayBlockingQueue<E> {
public EvictingBlockingQueue(int capacity) {
super(capacity);
}
@Override
public boolean offer(E e) {
while (!super.offer(e)) poll();
return true;
}
@Override
public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException {
while (!super.offer(e, timeout, unit)) poll();
return true;
}
}
Note that this implementation can unnecessarily remove an element if between two calls to super.offer(E)
another thread removes an element. This seems acceptable to me and I don't really see a practical way around it (ArrayBlockingQueue.lock
is package-private and java.util.concurrent
is a prohibited package so we can't place an implementation there to access and use the lock, etc.).