在java中有没有(无界)公平阻塞队列? [英] Is there any (unbounded) fair blocking queue in java?
问题描述
是否有阻塞队列的任何实现,如果多个消费者从同一队列中删除元素,则该队列保证公平的take()操作。我检查LinkedBlockingQueue,LinkedTransferQueue和看起来像他们都不公平。 ArrayBlockingQueue提供公平的操作,但它的有界。
Is there any implementation of blocking queue which guarantees fair take() operation if multiple consumers are removing element from the same queue. I checked LinkedBlockingQueue, LinkedTransferQueue and looks like both of them are unfair. ArrayBlockingQueue provides fair operation but its bounded.
推荐答案
我们可以使用无界队列像ConcurrentLinked队列公平的信号量。下面的类不实现BlockingQueue接口的所有方法,但只是其中的一些用于演示的目的。 main()方法仅作为测试。
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<T> {
private final Queue<T> queue;
private final Semaphore takeSemaphore;
public FairBlockingQueue() {
queue = new ConcurrentLinkedQueue<T>();
takeSemaphore = new Semaphore(0, true);
}
public FairBlockingQueue(Collection<T> c) {
queue = new ConcurrentLinkedQueue<T>(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<Object> q = new FairBlockingQueue<Object>();
Object o = q.poll();
assert o == null;
o = q.poll(1000);
assert o == null;
q.add(new Object());
q.add(new Object());
q.add(new Object());
o = q.take();
assert o != null;
o = q.poll();
assert o != null;
o = q.poll(1000);
assert o != null;
o = q.poll();
assert o == null;
}
}
这篇关于在java中有没有(无界)公平阻塞队列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!