BlockingArrayQueue源码解析 ReentrantLock的应用

349 阅读1分钟

put操作获取ReentrantLock独占锁
如果队列满,则调用notFull.await()
notFull是ReentrantLock的一个Condition 该线程会一直阻塞
那么什么时候会被释放呢?

    public void put(E e) throws InterruptedException {
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == items.length)
                //队列满 阻塞在notFull这个Condition上,当条件满足时会被唤醒
                notFull.await();
            enqueue(e);
        } finally {
            lock.unlock();
        }
    }

我们追踪notFull这个Condition,发现它是在dequeue 出队这个私有方法中唤醒的
每次有元素出队 都会试图唤醒等待在Condition中的put线程

    private E dequeue() {
        // assert lock.getHoldCount() == 1;
        // assert items[takeIndex] != null;
        final Object[] items = this.items;
        @SuppressWarnings("unchecked")
        E x = (E) items[takeIndex];
        items[takeIndex] = null;
        if (++takeIndex == items.length)
            takeIndex = 0;
        count--;
        if (itrs != null)
            itrs.elementDequeued();
        //元素移除,notFull条件达成 唤醒阻塞线程
        notFull.signal();
        return x;
    }