我正在编写一个BlockingQueue,并且想知道其他实现如何解决此问题:
如果我只有一个监视器(队列对象),并让生产者和消费者wait
,我将必须确保调用notifyAll
而不是notify
,否则即使队列已满,生产者也可能只向另一个等待中的生产者发出信号以继续。即使有可用的东西,也要让消费者等待。另一方面,对于许多线程和处理器,调用notifyAll
似乎不是一个可扩展的解决方案。BlockingQueue
是否使用两个监视器?一种是生产者在等待,一种是消费者在等待?然后,我将不得不以封装的方式同步队列和相关的监视器。那是路要走吗?
最佳答案
我不确定BlockingQueue
是如何完成的,但是一种可能的解决方案是使用 ReentrantLock
而不是synchronized
。
它具有与syncrhonized
相同的语义,但提供了一些改进。特别是,它可能具有其他线程可以在其上使用wait
的几种条件:
public class MyBlockingQueue<E> {
private Lock lock = new ReentrantLock();
private Condition notEmpty = lock.newCondition();
private Condition notFull = lock.newCondition();
public void put(E e) {
lock.lock();
try {
while (isFull()) notFull.await();
boolean wasEmpty = isEmpty();
...
if (wasEmpty) notEmpty.signal();
} finally {
lock.unlock();
}
}
public E take() {
lock.lock();
try {
while (isEmpty()) notEmpty.await();
boolean wasFull = isFull();
...
if (wasFull) notFull.signal();
...
} finally {
lock.unlock();
}
}
...
}