这里可以看到实现的接口有哪些(Serializable, Iterable, Collection, BlockingQueue, Queue),相应的ArrayBlockingQueue就有哪一些特性。
ArrayBlockingQueue由数组实现的有界阻塞队列。此队列命令元素FIFO(先入先出)。队列的头是队列中最长时间的元素,队列的尾部是队列中的元素最短时间。在队列尾部插入新元素,队列检索操作在队列头中获取元素。
这是一个经典的“有界缓冲区”,其中固定大小数组保存由生产者插入并由使用者提取的元素。一旦创建,容量就无法更改。试图将元素放到一个满的队列中,会导致操作阻塞;试图从空队列中获取元素也会类似地阻塞。
有以下的构造方法:
ArrayBlockingQueue(int capacity):使用给定的(固定)容量和默认访问策略创建一个ArrayBlockingQueue。
ArrayBlockingQueue(int capacity, boolean fair):使用给定的(固定)容量和指定的访问策略创建一个ArrayBlockingQueue。
可以看到capacity需要大于0,不然会有IllegalArgumentException异常,然后初始化this.items数组,对于传入的fair,用来构建ReentrantLock,使用公平锁还是非公平锁(sync = fair ? new FairSync() : new NonfairSync())。notEmpty与notNull获取Condition。
NonfairSync非公平锁:当锁处于无线程占有的状态,此时其他线程和在队列中等待的线程都可以抢占该锁。
FairSync公平锁:当锁处于无线程占有的状态,在其他线程抢占该锁的时候,都需要先进入队列中等待。
ArrayBlockingQueue(int capacity, boolean fair, Collection extends E> c):创建具有给定(固定)容量的ArrayBlockingQueue,指定的访问策略并最初包含给定集合的元素,以集合的迭代器的遍历顺序添加。
先是调用上一个构造方法,然后使用lock加锁,然后进行遍历添加,在finally里面解锁。
add(E e):在不超出队列容量的情况下立即执行此操作,则将指定元素插入此队列的尾部,成功时返回true,如果此队列已满,则抛出IllegalStateException。
这里使用的是继承的add方法,实现了offer方法。
后者的方法加了超时的时间控制,利用Condition的awaitNanos方法。
put(E e):将指定元素插入此队列的尾部,等待队列已满时空间可用。这里使用了notFull.await()阻塞写数据,在enqueue里面notEmpty.signal(),唤醒读数据。
poll方法:检索并删除此队列的头部,如果此队列为空,则返回null,这里调用的是dequeue(),里面有notFull.signal();相应的也有poll(long timeout, TimeUnit unit)方法。
take():检索并删除此队列的头部,必要时等待,直到元素可用。
peek():检索但不移除此队列的头部,如果此队列为空,则返回null。
remove(Object o):从此队列中删除指定元素的单个实例(如果存在)。
有什么讨论的内容,可以加我公众号: