java集合框架 arrayblockingqueue应用分析

2016-02-19 11:34 1 1 收藏

给自己一点时间接受自己,爱自己,趁着下午茶的时间来学习图老师推荐的java集合框架 arrayblockingqueue应用分析,过去的都会过去,迎接崭新的开始,释放更美好的自己。

【 tulaoshi.com - 编程语言 】

Queue
------------
1.ArrayDeque, (数组双端队列)
2.PriorityQueue, (优先级队列)
3.ConcurrentLinkedQueue, (基于链表的并发队列)
4.DelayQueue, (延期阻塞队列)(阻塞队列实现了BlockingQueue接口)
5.ArrayBlockingQueue, (基于数组的并发阻塞队列)
6.LinkedBlockingQueue, (基于链表的FIFO阻塞队列)
7.LinkedBlockingDeque, (基于链表的FIFO双端阻塞队列)
8.PriorityBlockingQueue, (带优先级的无界阻塞队列)
9.SynchronousQueue (并发同步阻塞队列)
-----------------------------------------------------
ArrayBlockingQueue
是一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素。
这是一个典型的“有界缓存区”,固定大小的数组在其中保持生产者插入的元素和使用者提取的元素。一旦创建了这样的缓存区,就不能再增加其容量。试图向已满队列中放入元素会导致操作受阻塞;试图从空队列中提取元素将导致类似阻塞。
此类支持对等待的生产者线程和消费者线程进行排序的可选公平策略。默认情况下,不保证是这种排序。然而,通过将公平性 (fairness) 设置为 true 而构造的队列允许按照 FIFO 顺序访问线程。公平性通常会降低吞吐量,但也减少了可变性和避免了“不平衡性”。
代码如下:

public class ArrayBlockingQueueE extends AbstractQueueE implements BlockingQueueE, 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();
}
}
……
}

来源:https://www.tulaoshi.com/n/20160219/1597879.html

延伸阅读
标签: Web开发
随着时代发展,javascript阵营里面出现了越来越多的优秀的框架,大大简化了我们的开发工作,在我们使用这些框架的时候是不是也应该饮水思源想想它们都是怎样构建起来的呢?如果你不满足于仅仅是使用一些现成的API,而是深入了解它们内部的实现机制(照某人的说法, API是贬值最快的东西),最好的办法就是阅读它们的源代码了,前提是你读得懂。...
VC应用程序框架提供的强大功能,为我们的开发提供了极大的方便,利用它可以很轻松地生成应用程序的框架.许多常用功能,例如文档的创建,文件的打开,保存等操作的大部分代码都由应用程序框架来完成.这些操作对于开发软件的用户而言是透明的。微软设计Visual C++的初衷是尽量向用户提供尽可能简单的接口,但是,正是因为应用框架的这一透明性,使VC...
Java.util 中的集合类包含 Java 中某些最常用的类。 最常用的集合类是 List 和 Map。 List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。 List 适用于按数值索引访问元素的情形。 Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作“键”和...
?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />   摘要:你想写出无需改变源代码就可以进行扩展的程序吗?这篇文章介绍了如何使用interface和动态class载入来创建高扩展性的系统。从中你也可以学习到如何令其他的编程者和用户不需你的源代码,就可以对程序进行扩展。首先我们看一个没有使用inter...
1.什么是模式? 模式,即pattern。其实就是解决某一类问题的方法论。你把解决某类问题的方法总结归纳到理论高度,那就是模式。 Alexander给出的经典定义是:每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心。通过这种方式,你可以无数次地使用那些已有的解决方案,无需在重复相同的工作。 模式有...

经验教程

774

收藏

87
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部