阻塞队列是一种生产者、消费者模式的利用;
ArrayBlockingQueue从源码角度来看,其实质是condition的一种利用

一、样例及原理

// == 1.队列初始化ArrayBlockingQueue queue = new ArrayBlockingQueue(100);// == 2.入队Thread threadA = new Thread(()->{    try {        queue.put(new Object());    } catch (InterruptedException e) {        e.printStackTrace();    }});threadA.start();// == 3.出队Thread threadB = new Thread(()->{    try {        Object object = queue.take();    } catch (InterruptedException e) {        e.printStackTrace();    }});threadB.start();

1.元素A退出队列并被生产流程

创立ArrayBlockingQueue时会构建一个数组,用来寄存元素;同时会创立一个notEmpty的condition条件。
①、生产者生产元素
元素A会寄存在数组中,同时会触发notEmpty这个condition的signal办法唤醒被阻塞的消费者。
②、消费者生产元素
此时另一个线程生产,本着FIFO准则元素A会被移除出数组,当数组元素的length=0时,触发await办法阻塞消费者

2.队列已满元素N被生产流程

见下图(逻辑相似,不做剖析了,懒~)

二、源码剖析

1.初始化

public ArrayBlockingQueue(int capacity, boolean fair) {    if (capacity <= 0)        throw new IllegalArgumentException();    // 初始化数组    this.items = new Object[capacity];    // fair=false,非偏心锁    lock = new ReentrantLock(fair);    // 两个condition,不空、不满    notEmpty = lock.newCondition();    notFull =  lock.newCondition();}

2.入队put

public void put(E e) throws InterruptedException {    checkNotNull(e);    final ReentrantLock lock = this.lock;    // ## 加锁,被中断则抛出异样(抛异样是doAcquireInterruptibly()与acquireQueued()的次要区别))    lock.lockInterruptibly();    try {        // -- 1.队列满了,await阻塞        while (count == items.length){            notFull.await();        }        // -- 2.队列未满,入队        enqueue(e);    } finally {        lock.unlock();    }}// -- 2.队列未满,入队逻辑java.util.concurrent.ArrayBlockingQueue#enqueueprivate void enqueue(E x) {    final Object[] items = this.items;    items[putIndex] = x;    if (++putIndex == items.length)        putIndex = 0;    count++;    // ## 唤醒notEmpty的condition    notEmpty.signal();}

3.出队take

public E take() throws InterruptedException {    final ReentrantLock lock = this.lock;    // 加锁    lock.lockInterruptibly();    try {        // -- 1.队列空,则阻塞        while (count == 0)            notEmpty.await();        // -- 2.队列不空,出队        return dequeue();    } finally {        lock.unlock();    }}// -- 2.队列不空,出队java.util.concurrent.ArrayBlockingQueue#dequeueprivate E dequeue() {    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;}