ArrayBlockingQueue 类实现了 BlockingQueue 接口。
有界的阻塞队列
- 基于数组来实现
有界也就意味着,它不能够存储无限多数量的元素。它有一个同一时间能够存储元素数量的上限。
你可以在对其初始化的时候设定这个上限,但之后就无法对这个上限进行修改了(译者注:
因为它是基于数组实现的,也就具有数组的特性:一旦初始化,大小就无法修改)。
ArrayBlockingQueue 内部以 FIFO(先进先出)的顺序对元素进行存储。队列中的头元素在所
有元素之中是放入时间最久的那个,而尾元素则是最短的那个。
ArrayBlockingQueue 支持对等待的生产者线程和使用者线程进行排序的可选公平策略。默认情况下,不保证是这种排序的。然而通过将公平性(fairness)设置为true,而构造的队列允许按照FIFO顺序访问线程。公平性通常会降低吞吐量,但也减少了可变性和避免了“不平衡性”。
以下是在使用 ArrayBlockingQueue 的时候对其初始化的一个示例:
// 创建一个具有给定(5)容量的 ArrayBlockingQueue,并且不可扩容,默认为非公平策略
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(5);
//创建一个具有给定(5)容量的 ArrayBlockingQueue,并且不可扩容,并指定公平策略
//int capacity 固定容量
//boolean fair定义是否为公平策略
ArrayBlockingQueue queue = ArrayBlockingQueue(5,true);
List<String> list = new ArrayList<String>();//创建集合对象;
list.add("1");//在集合里存入数据
list.add("2");
//Collection<? extends E> c 指定集合
ArrayBlockingQueue queue = ArrayBlockingQueue(5,true,list );
用代码表示ArrayBlockingQueue的基本用法:
import java.util.concurrent.ArrayBlockingQueue;
public static void main(String[] args) throws InterruptedException {
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(5);
// 添加元素
queue.add("s");
queue.add("f");
queue.add("e");
queue.add("g");
queue.add("h");
// 队列已满的前提下,继续存放元素会出现IllegalStateException
queue.add("l");
// 队列已满的前提下,继续存放元素会被舍弃并且返回false
boolean b = queue.offer("f");
// 队列已满的前提下继续存放元素会产生阻塞
// 直到队列中有元素被取出才会放开阻塞
queue.put("r");
// 定时阻塞 --- 允许一段时间的容错机制
boolean b = queue.offer("d", 3000, TimeUnit.MILLISECONDS);
//从这个队列中删除所有的元素。
queue.clear();
//如果此队列包含指定的元素,则返回 true 。
boolean contains = queue.contains("s");
//检索但不删除此队列的头,如果此队列为空,则返回 null 。
queue.peek()
//以适当的顺序返回该队列中的元素的迭代器。
Iterator<String> iterator = queue.iterator();
while(iterator.hasNext()) {
String next = iterator.next();
System.out.println(next);
}
//检索并删除此队列的头,等待指定的等待时间(如有必要)使元素变为可用。
//timeout:时间
//unit:时间单位
poll(long timeout, TimeUnit unit)
//从该队列中删除所有可用的元素,并将它们添加到给定的集合中。
//drainTo(Collection<? super E> c)
//最多从该队列中删除给定数量的可用元素,并将它们添加到给定的集合中。
//int drainTo(Collection<? super E> c, int maxElements)
}
//检索并删除此队列的头
queue.take();
// 如果队列为空,则返回null.如果队列不为空则检索并删除此队列的头
queue.poll();
这里说一下他们的区别:
使用take()函数,如果队列中没有数据,则线程wait释放CPU,而poll()则不会等待,直接返回null,因此如果你使用while(true)来获得队列元素,千万别用poll(),CPU会100%的。
// 队列已满的前提下,继续存放元素会被舍弃并且返回false
boolean b = queue.offer(“f”);
// 队列已满的前提下继续存放元素会产生阻塞
// 直到队列中有元素被取出才会放开阻塞
queue.put(“r”);
// 定时阻塞 — 允许一段时间的容错机制
boolean b = queue.offer(“d”, 3000, TimeUnit.MILLISECONDS);
空间耗尽时offer()函数不会等待,直接返回false,而put()则会wait。
自我总结,不对地方请指正。。。