I'd like to use a CircularFifoQueue
with spring ExecutorService
.
The following does not compile, because CircularFifoQueue
is not of type BlockingQueue
. But it shows what I'm trying to achieve:
int threads = 10;
int queueSize = 500;
new java.util.concurrent.ThreadPoolExecutor(threads, threads, 0L, TimeUnit.MILLISECONDS,
new CircularFifoQueue(queueSize));
With:
package org.apache.commons.collections4.queue;
public class CircularFifoQueue<E> extends AbstractCollection<E>
implements Queue<E>, BoundedCollection<E>, Serializable
Question: does the code above provide thread safety (as CircularFifoQueue
itself is not threadsafe)?
If not, how can I make it threadsafe?
You can synchronize using commons-collections QueueUtils.synchronizedQueue
Queue queue = QueueUtils.synchronizedQueue(new CircularFifoQueue());
But according to javadoc it needs additional synchronization for serial access:
In order to guarantee serial access, it is critical that all access to the backing queue is accomplished through the returned queue.
It is imperative that the user manually synchronize on the returned queue when iterating over it:
Queue queue = QueueUtils.synchronizedQueue(new CircularFifoQueue()); ... synchronized(queue) { Iterator i = queue.iterator(); // Must be in synchronized block while (i.hasNext()) foo(i.next()); } }
Failure to follow this advice may result in non-deterministic behavior.
Work queues are meant to be blocking, and hence you would need to add a decorator
to make that CircularFifoQueue
a BLockingQueue
.
class BlockingCircularFifoQueue<E> implements BlockingQueue<E>{
private CircularFifoQueue<E> backingCollection;
...
}
And delegate to the backing collection when needed. You would need to get Conditions and Lock right of course.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With