集合框架 Queue---ArrayBlockingQueue
转载自 集合框架 Queue---ArrayBlockingQueue
- 摘要:java.util.concurrent类
- java.util.concurrent
类 ArrayBlockingQueue<E>
java.lang.Object
java.util.AbstractCollection<E>
java.util.AbstractQueue<E>
java.util.concurrent.ArrayBlockingQueue<E>
类型参数:
E - 在此 collection 中保持的元素类型
所有已实现的接口:
Serializable, Iterable<E>, Collection<E>, BlockingQueue<E>, Queue<E>
public class ArrayBlockingQueue<E>
extends AbstractQueue<E>
implements BlockingQueue<E>, Serializable
一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素。
这是一个典型的“有界缓存区”,固定大小的数组在其中保持生产者插入的元素和使用者提取的元素。一旦创建了这样的缓存区,就不能再增加其容量。试图向已满队列中放入元素会导致操作受阻塞;试图从空队列中提取元素将导致类似阻塞。
此类支持对等待的生产者线程和使用者线程进行排序的可选公平策略。默认情况下,不保证是这种排序。然而,通过将公平性 (fairness) 设置为 true 而构造的队列允许按照 FIFO 顺序访问线程。公平性通常会降低吞吐量,但也减少了可变性和避免了“不平衡性”。
此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选 方法。
此类是 Java Collections Framework 的成员。
实现了Serializable可知道是其实线程安全的
源代码:
public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable { /** 队列元素 数组 */ private final E[] items; /** 获取、删除元素时的索引(take, poll 或 remove操作) */ private int takeIndex; /** 添加元素时的索引(put, offer或 add操作) */ private int putIndex; /** 队列元素的数目*/ private int count; /** 锁 */ private final ReentrantLock lock; /** 获取操作时的条件 */ private final Condition notEmpty; /** 插入操作时的条件 */ private final Condition notFull; //超出数组长度时,重设为0 final int inc(int i) { return (++i == items.length)? 0 : i; } /** * 插入元素(在获得锁的情况下才调用) */ private void insert(E x) { items[putIndex] = x; putIndex = inc(putIndex); ++count; notEmpty.signal(); } /** * 获取并移除元素(在获得锁的情况下才调用) */ private E extract() { final E[] items = this.items; E x = items[takeIndex]; items[takeIndex] = null; takeIndex = inc(takeIndex);//移到下一个位置 --count; notFull.signal(); return x; } /** * 删除i位置的元素 */ void removeAt(int i) { final E[] items = this.items; // if removing front item, just advance if (i == takeIndex) { items[takeIndex] = null; takeIndex = inc(takeIndex); } else { // 把i后面的直到putIndex的元素都向前移动一个位置 for (;;) { int nexti = inc(i); if (nexti != putIndex) { items[i] = items[nexti]; i = nexti; } else { items[i] = null; putIndex = i; break; } } } --count; notFull.signal(); } /** *构造方法,指定容量,默认策略(不是按照FIFO的顺序访问) */ public ArrayBlockingQueue(int capacity) { this(capacity, false); } /** *构造方法,指定容量及策略 */ public ArrayBlockingQueue(int capacity, boolean fair) { if (capacity <= 0) throw new IllegalArgumentException(); this.items = (E[]) new Object[capacity]; lock = new ReentrantLock(fair); notEmpty = lock.newCondition(); notFull = lock.newCondition(); } /** * 通过集合构造 */ public ArrayBlockingQueue(int capacity, boolean fair, Collection<? extends E> c) { this(capacity, fair); if (capacity < c.size()) throw new IllegalArgumentException(); for (Iterator<? extends E> it = c.iterator(); it.hasNext();) add(it.next()); } /** * 插入元素到队尾(super调用offer方法) * public boolean add(E e) { * if (offer(e)) * return true; * else * throw new IllegalStateException("Queue full"); * } * 将指定的元素插入到此队列的尾部(如果立即可行且不会超过该队列的容量), * 在成功时返回 true,如果此队列已满,则抛出 IllegalStateException。 */ public boolean add(E e) { return super.add(e); } /** * 将指定的元素插入到此队列的尾部(如果立即可行且不会超过该队列的容量), * 在成功时返回 true,如果此队列已满,则返回 false。 */ public boolean offer(E e) { if (e == null) throw new NullPointerException(); final ReentrantLock lock = this.lock; lock.lock(); try { if (count == items.length) return false; else { insert(e); return true; } } finally { lock.unlock(); } } /** * 将指定的元素插入此队列的尾部,如果该队列已满,则等待可用的空间。 */ public void put(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); final E[] items = this.items; final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { try { while (count == items.length) notFull.await(); } catch (InterruptedException ie) { notFull.signal(); // propagate to non-interrupted thread throw ie; } insert(e); } finally { lock.unlock(); } } /** * 将指定的元素插入此队列的尾部,如果该队列已满,则在到达指定的等待时间之前等待可用的空间。 */ public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { for (;;) { if (count != items.length) { insert(e); return true; } if (nanos <= 0)//如果时间到了就返回 return false; try { nanos = notFull.awaitNanos(nanos); } catch (InterruptedException ie) { notFull.signal(); // propagate to non-interrupted thread throw ie; } } } finally { lock.unlock(); } } //获取并移除此队列的头,如果此队列为空,则返回 null。 public E poll() { final ReentrantLock lock = this.lock; lock.lock(); try { if (count == 0) return null; E x = extract(); return x; } finally { lock.unlock(); } } //获取并移除此队列的头部,在元素变得可用之前一直等待(如果有必要)。 public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { try { while (count == 0) notEmpty.await(); } catch (InterruptedException ie) { notEmpty.signal(); // propagate to non-interrupted thread throw ie; } E x = extract(); return x; } finally { lock.unlock(); } } //获取并移除此队列的头部,在指定的等待时间前等待可用的元素(如果有必要)。 public E poll(long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { for (;;) { if (count != 0) { E x = extract(); return x; } if (nanos <= 0) return null; try { nanos = notEmpty.awaitNanos(nanos); } catch (InterruptedException ie) { notEmpty.signal(); // propagate to non-interrupted thread throw ie; } } } finally { lock.unlock(); } } //获取但不移除此队列的头;如果此队列为空,则返回 null。 public E peek() { final ReentrantLock lock = this.lock; lock.lock(); try { return (count == 0) ? null : items[takeIndex]; } finally { lock.unlock(); } } /** * 返回此队列中元素的数量。 */ public int size() { final ReentrantLock lock = this.lock; lock.lock(); try { return count; } finally { lock.unlock(); } } /** *返回在无阻塞的理想情况下(不存在内存或资源约束)此队列能接受的其他元素数量。 */ public int remainingCapacity() { final ReentrantLock lock = this.lock; lock.lock(); try { return items.length - count; } finally { lock.unlock(); } } /** * 从此队列中移除指定元素的单个实例(如果存在)。 */ public boolean remove(Object o) { if (o == null) return false; final E[] items = this.items; final ReentrantLock lock = this.lock; lock.lock(); try { int i = takeIndex; int k = 0; for (;;) { if (k++ >= count) return false; if (o.equals(items[i])) { removeAt(i); return true; } i = inc(i); } } finally { lock.unlock(); } } /** * 如果此队列包含指定的元素,则返回 true。 */ public boolean contains(Object o) { if (o == null) return false; final E[] items = this.items; final ReentrantLock lock = this.lock; lock.lock(); try { int i = takeIndex; int k = 0; while (k++ < count) { if (o.equals(items[i])) return true; i = inc(i); } return false; } finally { lock.unlock(); } } }
集合框架 Queue---ArrayBlockingQueue相关推荐
- Java 集合框架分析:JAVA集合中的一些边边角角的知识
相关文章: Java 集合框架分析:Set http://blog.csdn.net/youyou1543724847/article/details/52733723 Java 集合框架分析:Lin ...
- Java 集合框架分析:线程安全的集合
相关文章: Java 集合框架分析:Set http://blog.csdn.net/youyou1543724847/article/details/52733723 Java 集合框架分析:Lin ...
- java集合框架容器 java框架层级 继承图结构 集合框架的抽象类 集合框架主要实现类...
本文关键词: java集合框架 框架设计理念 容器 继承层级结构 继承图 集合框架中的抽象类 主要的实现类 实现类特性 集合框架分类 集合框架并发包 并发实现类 什么是容器? 由一个或多个确 ...
- java面试题之简单介绍一下集合框架
集合框架分为三块:List列表.Set集合.Map映射 List列表在数据结构上可以被看做线性表,常用的有ArrayList和LinkList(不常用的有Vector(类似于ArrayList)),他 ...
- 集合框架 Queue---BlockingQueue详解
转载自 集合框架 Queue---BlockingQueue详解 摘要:本例介绍一个特殊的队列:BlockingQueue,如果BlockingQueue是空的,从BlockingQueue取东西的 ...
- java集合框架的实现
集合框架的具体实现 集合框架的实现有如下几类: 通用实现 特殊实现 并发实现 包装实现 简便实现 抽象实现 Set实现 Set实现分为通用和特殊实现 通用实现 通用实现有三种: HashSet Tre ...
- Java集合框架是什么?说出一些集合框架的优点?
干货太重,且文字比较多.需要花费时间与耐心细细咀嚼,但是真的能收获到很多. 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector.Stack.HashTable和Array.随着集合 ...
- Java的并发集合框架
文章目录 一.并发集合框架 1. 简介 2. 接口Iterable 2. 接口Collection 3. 接口List 4. 接口Set 5. 接口Queue 6. Deque 二.非阻塞队列 1. ...
- 1.Java集合框架是什么?说出一些集合框架的优点?
1.Java集合框架是什么?说出一些集合框架的优点? 干货太重,且文字比较多.需要花费时间与耐心细细咀嚼,但是真的能收获到很多. 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector ...
最新文章
- 自己写的一个简单的购物车的登录购买
- java的知识点34——任务定时调度(多线程)
- 数据中心液体冷却方案正在兴起的五大原因
- 排序算法 | 直接插入排序算法的图解、实现、复杂度和稳定性分析
- 通过数据库动态视图'v$',查看数据库信息
- 扫描代码重大漏洞 java_超过 75% 的开源软件安全漏洞存在于间接依赖中 | Linux 中国...
- 统计词语出现次数python_Python实战教程:如何统计序列中元素的出现频度
- pph上传文件到window服务器,[upload_labs]文件上传绕过小结
- window难以实现的linux,工欲善其事必先利其器--几步实现window与linux之间的文件共享...
- SQL 被当成代码?谷歌的理由绝了!
- SqlServer的代理问题
- ubuntu安装deb文件
- Excel怎么隔列设定不同的背景颜色
- 微软关闭了两种攻击途径:Office 宏、RDP 暴力破解
- 苹果官网下架iPhone 8;破解百度网盘的Pandownload开发者被捕;三大运营商年内上线5G消息 | EA周报...
- python调用不起来chrome_python调用selenium打开chrome浏览器失败
- stm32f405rgt6与as5048a的SPI通信问题
- 茗香茶艺网/茶叶宣传网站
- oh my zsh的安装与配置
- 独立窗口打开多个Excel
热门文章
- [设计模式]装饰模式
- [剑指offer]面试题9:斐波那契数列
- Abstract Factory(抽象工厂)--对象创建模式
- linux加大ram 内核需要,Linux 5.1内核发布:io_uring接口+支持持久性内存用作RAM
- 三调 图斑地类面积_三调对于最小上图图斑面积的要求是:
- background图片不显示_一种解决Retina屏幕1px边框显示问题的方案
- Leetcode 35.搜索插入位置 二分
- 数据结构 堆中的路径(最小堆)
- Java实现生产消费模型的5种方式
- 2019-03-12-算法-进化(合并两个有序数组)