版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Kurozaki_Kun/article/details/80877612
Java的java.util.concurrent.*包下有许多在并发场景下使用的集合,ArrayBlockingQueue是其中之一,它是一个循环队列,这个队列的特别之处在于take方法与put方法,分别对应队列的元素出列和元素入列操作,当队列为空时,take会使得线程进入等待状态,直到队列不为空,有元素能够出列才会继续执行;同理,当队列满时,put方法也会使得线程进入等待状态。
实际上这是一个生产者-消费者模型,按照理解, 自己也试着实现了一个,代码如下
/** * Created by YotWei on 2018/7/1. */ public class BlockingQueue<E> { /** * 有界队列内部固定长度,因此可以用数组实现 */ private Object[] elements; /** * 队列的头和尾下标 */ private int head = 0, tail = 0; /** * 队列目前的长度 */ private int size; private ReentrantLock lock = new ReentrantLock(); private Condition notEmpty = lock.newCondition(); private Condition notFull = lock.newCondition(); public BlockingQueue(int capacity) { this.elements = new Object[capacity]; } public void put(E e) { lock.lock(); try { while (size == elements.length) notFull.await(); elements[tail] = e; if (++tail == elements.length) { tail = 0; } size++; notEmpty.signal(); } catch (InterruptedException ex) { ex.printStackTrace(); } finally { lock.unlock(); } } public E take() { lock.lock(); E e = null; try { while (size == 0) { notEmpty.await(); } e = (E) elements[head]; elements[head] = null; if (++head == elements.length) head = 0; size--; notFull.signal(); } catch (InterruptedException ex) { ex.printStackTrace(); } finally { lock.unlock(); } return e; } public int size() { lock.lock(); try { return size; } finally { lock.unlock(); } } }
实际上ArrayBlockingQueue还包含许多其它方法,这两个是最核心的。