I need to fetch data from the queue in a round-robin concurrent way. I am looking for a collection that implements such behavior. After some digging, I cannot find one. How would I implement one?
I was looking at the ConcurrentLinkedQueue, but I am not sure how to make it circular. I need this collection to be highly performant.
I'm guessing I can do it with ConcurrentLinkedDeque. By using an iterator, I should be able to iterate all the way to the end, and once the end is reached I can re-create my iterator and go from the beginning.
=============================UPDATE===========================
Elements will be added to such collection by several threads during the initialization phase. Concurrent collection's state will be properly visible to the consumer threads that will be consuming one item at a time from it. Once the application is in a running state, elements won't be added to the collection. Only iteration and consumption of one element at a time by each thread in a cyclic fashion.
Given your revised question, this is what I would recommend:
For the initializing phase, use a concurrent Queue or Deque to accumulate the elements. Any implementation will do.
Once that phase is complete, create an instance of the following RoundRobin class from the queue object, and use its get method to the cycle through its elements.
public class RoundRobin <E> {
private final AtomicInteger next = new AtomicInteger(0);
private final E[] elements;
public RoundRobin(Collection<E> queue, Class<E> clazz) {
this.elements = queue.toArray(Array.newInstance(clazz, 0));
}
public E get() {
return elements[next.getAndIncrement() % elements.length];
}
}
The RoundRobin class is thread-safe and get is concurrent.
If the elements collection is mutated while you are constructing the RoundRobin, then the resulting RoundRobin state may not be the same as the final state of queue. From my reading of your stated requirements, that is OK.
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