Is there any implementation of blocking queue which guarantees fair take() operation if multiple consumers are removing element from the same queue. I checked LinkedBlocking
We can implement an unbounded fair blocking queue using an unbounded queue like ConcurrentLinked queue and a fair Semaphore. The class below doesn't implement all methods from the BlockingQueue interface but just a few of them for demonstration purposes. The main() method is written as a test only.
public class FairBlockingQueue {
private final Queue queue;
private final Semaphore takeSemaphore;
public FairBlockingQueue() {
queue = new ConcurrentLinkedQueue();
takeSemaphore = new Semaphore(0, true);
}
public FairBlockingQueue(Collection c) {
queue = new ConcurrentLinkedQueue(c);
takeSemaphore = new Semaphore(c.size(), true);
}
public T poll() {
if (!takeSemaphore.tryAcquire()) {
return null;
}
return queue.poll();
}
public T poll(long millis) throws InterruptedException {
if (!takeSemaphore.tryAcquire(millis, TimeUnit.MILLISECONDS)) {
return null;
}
return queue.poll();
}
public T take() throws InterruptedException {
takeSemaphore.acquire();
return queue.poll();
}
public void add(T t) {
queue.add(t);
takeSemaphore.release();
}
public static void main(String[] args) throws Exception {
FairBlockingQueue