BlockingQueue设计有多个显示器

Fra*_*fka 3 java synchronization monitor blocking java.util.concurrent

我正在写一个BlockingQueue,我想知道其他实现如何解决这个问题:

如果我只有一个监视器(队列对象)并让生产者和消费者wait,我将不得不确保notifyAll而不是notify被调用,否则生产者可能只发信号通知另一个等待生成器,即使队列已满.即使有东西可供消费者等待.另一方面,notifyAll对许多线程和处理器而言,调用似乎不是可扩展的解决方案.

不要BlockingQueues使用两台显示器?一个是生产者等待,一个是消费者等待?然后我将以封装的方式同步队列和相关监视器.这是要走的路吗?

axt*_*avt 5

我不确定它是如何完成的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();
        }
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • @Franz:是的,他们使用两个锁进行一些优化,如评论中所述.但是,"ArrayBlockingQueue"使用完全如上所示的单个锁. (2认同)