Java中的ArrayBlockingQueue类
ArrayBlockingQueue 类是由一个数组支持的有界阻塞队列。有界指的是队列的大小是固定的。一旦创建,容量就不能更改。尝试将元素放入满队列中将导致操作阻塞。同样,尝试从空队列中取出元素也会被阻塞。可以通过在ArrayBlockingQueue构造函数中传递capacity参数来实现ArrayBlockingQueue的有限制。这个队列以 先进先出(FIFO) 的方式来排序元素。这意味着,这个队列的头部是该队列中已有元素中最老的元素。
这个队列的尾部是该队列中已有元素中最新的元素。新插入的元素总是插入到队列的尾部,而队列检索操作则获得队列头部的元素。
这个类及其迭代器实现了所有 集合 和 迭代器 接口的可选方法。这个类是Java Collections Framework的一部分。
ArrayBlockingQueue的层次结构

这个类扩展了 AbstractQueue
声明
public class ArrayBlockingQueue
在这里, E 是存储在集合中的元素的类型。
ArrayBlockingQueue的构造函数
在这里, capacity 是 **** 数组阻塞队列的大小。
1. ArrayBlockingQueue(int capacity) :使用给定的capacity(固定)创建一个ArrayBlockingQueue,并使用默认访问策略。
ArrayBlockingQueue<E> abq = new ArrayBlockingQueue<E>(int capacity);
2. ArrayBlockingQueue(int capacity, boolean fair) :使用给定的capacity(固定)和指定的访问策略创建一个ArrayBlockingQueue。如果公平值为true,则处于插入或删除阻塞状态的线程的队列访问按FIFO顺序进行处理;如果为false,访问顺序是未指定的。
ArrayBlockingQueue<E> abq = new ArrayBlockingQueue<E>(int capacity, boolean fair);
3. ArrayBlockingQueue(int capacity, boolean fair,Collection c) :使用给定的capacity(固定)、指定的访问策略和最初包含给定集合的元素创建一个ArrayBlockingQueue,这些元素按照集合的迭代器的遍历顺序添加。如果fair值为true,则处于插入或删除阻塞状态的线程的队列访问按FIFO顺序进行处理;如果为false,则访问顺序是未指定的。
ArrayBlockingQueue<E> abq = new ArrayBlockingQueue<E>(int capacity, boolean fair, Collection c);
示例:
// Java程序演示
// ArrayBlockingQueue(int initialCapacity)
// 构造函数
import java.util.concurrent.ArrayBlockingQueue;
public class ArrayBlockingQueueDemo {
public static void main(String[] args)
{
// 定义ArrayBlockingQueue的容量
int capacity = 15;
// 使用ArrayBlockingQueue(int initialCapacity)构造函数创建ArrayBlockingQueue对象
ArrayBlockingQueue<Integer> abq = new ArrayBlockingQueue<Integer>(capacity);
// 添加数字
abq.add(1);
abq.add(2);
abq.add(3);
// 打印队列
System.out.println("ArrayBlockingQueue:" + abq);
}
}
输出:
ArrayBlockingQueue:[1, 2, 3]
基本操作
1. 添加元素
add(E e)方法将传递给该方法的元素插入到该队列的尾部。如果添加的元素超出队列的容量,该方法将抛出异常 IllegalStateException 。 如果元素添加成功,此方法返回true;否则,会抛出异常。
// Java程序演示向ArrayBlockingQueue中添加元素
import java.util.concurrent.ArrayBlockingQueue;
public class AddingElementsExample {
public static void main(String[] args)
{
// 定义ArrayBlockingQueue的容量
int capacity = 15;
// 使用ArrayBlockingQueue(int initialCapacity)构造函数创建ArrayBlockingQueue对象
ArrayBlockingQueue<Integer> abq = new ArrayBlockingQueue<Integer>(capacity);
// 添加数字
abq.add(1);
abq.add(2);
abq.add(3);
// 打印队列
System.out.println("ArrayBlockingQueue:" + abq);
}
}
输出
ArrayBlockingQueue:[1, 2, 3]
2. 删除元素
remove(Object o)方法从队列中删除指定元素的单个实例,如果该元素存在则删除。我们可以说,如果队列中存在一个或多个这样的元素,则该方法删除一个元素e使得o.equals(e)成立。如果队列包含要删除的指定元素,则remove()方法返回true。
// Java程序演示从AbstractQueue中删除元素
import java.util.concurrent.ArrayBlockingQueue;
public class RemovingElementsExample {
public static void main(String[] args)
{
// 定义ArrayBlockingQueue的容量
int capacity = 15;
// 创建ArrayBlockingQueue对象
ArrayBlockingQueue<Integer> abq = new ArrayBlockingQueue<Integer>(capacity);
// 添加数字
abq.add(1);
abq.add(2);
abq.add(3);
// 打印队列
System.out.println("ArrayBlockingQueue:" + abq);
// 删除223
boolean response = abq.remove(2);
// 打印队列
System.out.println("删除2: " + response);
// 打印队列
System.out.println("队列包含 " + abq);
// 删除所有元素
abq.clear();
// 打印队列
System.out.println("ArrayBlockingQueue: " + abq);
}
}
输出
ArrayBlockingQueue:[1, 2, 3]
删除2: true
队列包含 [1, 3]
ArrayBlockingQueue:[]
3. 访问元素
Queue 接口提供的peek()方法用于返回队列的头部。它检索但不删除此队列的头部。如果队列为空,则此方法返回null。
// Java程序演示访问ArrayBlockingQueue的元素
import java.util.concurrent.ArrayBlockingQueue;
public class AccessingElementsExample {
public static void main(String[] args)
{
// 定义ArrayBlockingQueue的容量
int capacity = 5;
// 创建ArrayBlockingQueue对象
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(capacity);
// 向ArrayBlockingQueue添加元素
queue.add(23);
queue.add(32);
queue.add(45);
queue.add(12);
// 添加数字后打印队列
System.out.println("添加数字后队列为 ");
System.out.println(queue);
// 使用peek()方法打印队列的头部
System.out.println("队列的头部 " + queue.peek());
}
}
输出
添加数字后队列为
[23, 32, 45, 12]
队列的头部 23
4. 遍历
ArrayBlockingQueue类的iterator()方法用于返回一个迭代器,该迭代器包含与此队列相同的元素,按适当的顺序。从此方法返回的元素包含从第一个(头部)到最后(尾部)的元素。返回的迭代器是弱一致的。
// Java程序演示数组阻塞队列的迭代
import java.util.concurrent.ArrayBlockingQueue;
import java.util.*;
public class TraversingExample {
public static void main(String[] args)
{
// 定义阻塞队列的容量
int capacity = 5;
// 创建ArrayBlockingQueue对象
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(capacity);
// 添加5个元素到ArrayBlockingQueue
queue.offer("User");
queue.offer("Employee");
queue.offer("Manager");
queue.offer("Analyst");
queue.offer("HR");
// 打印队列
System.out.println("Queue is " + queue);
// 调用iterator()方法并创建一个迭代器
Iterator iteratorValues = queue.iterator();
// 打印迭代器元素
System.out.println("\nThe iterator values:");
while (iteratorValues.hasNext()) {
System.out.println(iteratorValues.next());
}
}
}
输出
Queue is [User, Employee, Manager, Analyst, HR]
The iterator values:
User
Employee
Manager
Analyst
HR
ArrayBlockingQueue的方法
这里, E 是集合中保存的元素类型
| 方法 | 描述 |
|---|---|
| add(E e) | 如果队列未满,则将指定元素插入队列尾部,成功则返回true,如果队列已满则抛出IllegalStateException异常。 |
| clear() | 原子性地移除队列中的所有元素。 |
| contains(Object o) | 如果队列包含指定元素,则返回true。 |
| drainTo(Collection super E> c) | 从队列中移除所有可用的元素,并将它们添加到给定的集合中。 drainTo(Collection super E> c, int maxElements) | 最多从队列中移除给定数量的可用元素,并将它们添加到给定的集合中。 forEach(Consumer super E> action) | 对Iterable中的每个元素执行指定的操作,直到所有元素都被处理或操作抛出异常。 iterator() | 返回迭代器,迭代队列中的元素以正确的顺序输出。 offer(E e) | 如果队列未满,则将指定元素插入到队列尾部,成功则返回true,如果队列已满则返回false。 offer(E e, long timeout, TimeUnit unit) | 将指定元素插入到队列尾部,如果队列已满,则等待指定时间,直到队列有空间可用。 put(E e) | 将指定元素插入到队列尾部,如果队列已满,则等待直到有空间可用。 remainingCapacity() | 返回此队列可以接受的附加元素数(在没有内存或资源限制的情况下)。 remove(Object o) | 从队列中删除指定元素的单个实例(如果存在)。 removeAll(Collection> c) |
删除该集合中还包含在指定集合中的所有元素(可选操作)。 |
| removeIf(Predicate super E> filter) | 删除该集合中满足给定断言的所有元素。 retainAll(Collection> c) |
仅保留该集合中包含在指定集合中的元素(可选操作)。 |
| size() | 返回队列中的元素数。 |
| spliterator() | 返回在队列中的元素上进行分割的Spliterator。 |
| toArray() | 返回一个数组,其中包含队列中的所有元素,以正确的顺序。 |
| toArray(T[] a) | 返回一个数组,其中包含队列中的所有元素以正确的顺序;返回数组的运行时类型是指定数组的类型。 |
在java.util.AbstractQueue类中声明的方法
| 方法 | 描述 |
|---|---|
| addAll(Collection extends E> c) | 将指定集合中的所有元素添加到此队列中。 element() | 检索但不删除此队列的头。 remove() | 检索并删除此队列的头。 ### java.util.AbstractCollection类中声明的方法 方法 | 描述 |
如果此集合包含指定集合中的所有元素,则返回true。 |
| isEmpty() | 如果此集合不包含元素,则返回true。 |
| toString() | 返回此集合的字符串表示形式。 |
java.util.concurrent.BlockingQueue接口中声明的方法
| 方法 | 描述 |
|---|---|
| poll(long timeout, TimeUnit unit) | 检索并删除此队列的头,等待指定的等待时间(如果需要)以使元素变得可用。 |
| take() | 检索并删除此队列的头,如果必要,一直等到有元素可用。 |
java.util.Collection接口中声明的方法
| 方法 | 描述 |
|---|---|
| addAll(Collection extends E> c) | 将指定集合中的所有元素添加到此集合中(可选操作)。 containsAll(Collection> c) |
如果此集合包含指定集合中的所有元素,则返回true。 |
| equals(Object o) | 将指定的对象与此集合进行比较以测试相等性。 |
| hashCode() | 返回此集合的哈希码值。 |
| isEmpty() | 如果此集合不包含元素,则返回true。 |
| parallelStream() | 返回源以此集合为其源的可能并行流。 |
| stream() | 返回以此集合为源的顺序流。 |
| toArray(IntFunction<T[]> generator) | 返回包含此集合中所有元素的数组,使用提供的生成器函数来分配返回的数组。 |
java.util.Queue接口中声明的方法
| 方法 | 描述 |
|---|---|
| element() | 检索但不删除此队列的头。 |
| peek() | 检索但不删除此队列的头部,如果此队列为空,则返回null。 |
| poll() | 检索并删除此队列的头部,如果此队列为空,则返回null。 |
| remove() | 检索并删除此队列的头部。 |
结论: ArrayBlockingQueue通常用于线程安全的环境中,当您希望阻止两个或多个线程对单个资源进行操作时,只允许一个线程。此外,我们可以使用容量限制因素阻止线程。
参考文献: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ArrayBlockingQueue.html
极客教程