本文讲,大家看看源码即可。

2.2 remove(Object o)

 public boolean remove(Object o) {
        if (o == null) return false;
        final Object[] items = this.items;
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            if (count > 0) {
                final int putIndex = this.putIndex;
                int i = takeIndex;
                do {
                    if (o.equals(items[i])) {
                        // 主要删除逻辑
                        removeAt(i);
                        return true;
                    }
                    if (++i == items.length)
                        i = 0;
                } while (i != putIndex);
            }
            return false;
        } finally {
            lock.unlock();
        }
    }
void removeAt(final int removeIndex) {
        // assert lock.getHoldCount() == 1;
        // assert items[removeIndex] != null;
        // assert removeIndex >= 0 && removeIndex < items.length;
        final Object[] items = this.items;
        if (removeIndex == takeIndex) {
            // removing front item; just advance
            items[takeIndex] = null;
            if (++takeIndex == items.length)
                takeIndex = 0;
            count--;
            if (itrs != null)
                itrs.elementDequeued();
        } else {
            // an "interior" remove

            // slide over all others up through putIndex.
            // 此时removeIndex != takeIndex
            // 为啥要执行下面的代码,大家可以按照上面图片的最后状态,
            // 按照下面代码走一下,就明白了.主要是设置putIndex
            final int putIndex = this.putIndex;
            for (int i = removeIndex;;) {
                int next = i + 1;
                if (next == items.length)
                    next = 0;
                if (next != putIndex) {
                    items[i] = items[next];
                    i = next;
                } else {
                    items[i] = null;
                    this.putIndex = i;
                    break;
                }
            }
            count--;
            if (itrs != null)
                itrs.removedAt(removeIndex);
        }
        notFull.signal();
    }

2.3 解释解释Itrs

    // 当前活动迭代器的共享状态; 允许队列操作更新迭代器的状态;
    transient Itrs itrs = null;

这个变量可以理解成,在一个线程使用迭代器时,其他的线程可以对队列进行更新操作的一个保障。
源码注释中对Itrs的描述,迭代器和它们的队列之间共享数据,允许在删除元素时修改队列以更新迭代器。 我们可以看到对队列进行了删除操作时,队列都会执行下面的语句

   if (itrs != null)
      itrs.removedAt(removeIndex);

初始化该值是在使用迭代器时

    public Iterator<E> iterator() {
        return new Itr();
    }

    ...

  Itr() {
            // assert lock.getHoldCount() == 0;
            lastRet = NONE;
            final ReentrantLock lock = ArrayBlockingQueue.this.lock;
            lock.lock();
            try {
                    ...
                        itrs = new Itrs(this);
                    ...
                }
            } finally {
                lock.unlock();
            }
        }

3. 总结

ArrayBlockingQueue的实现整体不难,使用ReetrantLock保证了线程安全,putIndex与takeIndex分别维护入队与出队的位置,一起构成一个循环数组

06-10 04:59