继承体系

image.png

数据结构

  1. public class ArrayBlockingQueue<E> extends AbstractQueue<E>
  2. implements BlockingQueue<E>, java.io.Serializable {
  3. final Object[] items;// 数组实现
  4. int takeIndex;// 即将拿出的元素索引
  5. int putIndex;// 即将放入的元素索引
  6. // 并发控制的锁
  7. final ReentrantLock lock;
  8. }

put() & offer()

put加入队列,如果队列满了则等待;offer则立即返回错误

  1. public void put(E e) throws InterruptedException {
  2. checkNotNull(e);
  3. final ReentrantLock lock = this.lock;
  4. lock.lockInterruptibly();
  5. try {
  6. // 数组满了则等待
  7. while (count == items.length)
  8. notFull.await();
  9. // 入队
  10. enqueue(e);
  11. } finally {
  12. lock.unlock();
  13. }
  14. }
  15. public boolean offer(E e) {
  16. // 如果传的是null 直接抛空指针异常
  17. checkNotNull(e);
  18. final ReentrantLock lock = this.lock;
  19. lock.lock();
  20. try {
  21. // 如果已经满了,返回false
  22. if (count == items.length)
  23. return false;
  24. else {
  25. // 调用 enqueue 插入数据
  26. enqueue(e);
  27. return true;
  28. }
  29. } finally {
  30. lock.unlock();
  31. }
  32. }
  33. private void enqueue(E x) {
  34. // assert lock.getHoldCount() == 1;
  35. // assert items[putIndex] == null;
  36. final Object[] items = this.items;
  37. items[putIndex] = x;
  38. // 入队成功后putIndex++
  39. // 数组满了putIndex重置为0(这里可以理解为0并不是队列的尾,队列的尾是在移动的类似于一个环,队列尾是putIndex++)
  40. if (++putIndex == items.length)
  41. putIndex = 0;
  42. count++;
  43. // 已经添加数据,唤醒not Empty
  44. notEmpty.signal();
  45. }

take() & poll()

take如果队列为空则阻塞;poll为空则返回null

public E take() throws InterruptedException {
    final ReentrantLock lock = this.lock;
      // 可响应中断
    lock.lockInterruptibly();
    try {
          // 队列已空
        while (count == 0)
              // 等待 ”队列不为空“ Condition
            notEmpty.await();
          // 调用 dequeue 取元素
        return dequeue();
    } finally {
        lock.unlock();
    }
}

public E poll() {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        return (count == 0) ? null : dequeue();
    } finally {
        lock.unlock();
    }
}

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;
      // 如果取完就重置 takeIndex,继续从0开始取
    if (++takeIndex == items.length)
        takeIndex = 0;
    count--;
    if (itrs != null)
        itrs.elementDequeued();
      // 走到这里说明已经取一条了
      // 这个时候需要唤醒 "队列没有满" Condition
    notFull.signal();
    return x;
}