# Java `ArrayBlockingQueue`类

> 原文： [https://howtodoinjava.com/java/collections/java-arrayblockingqueue/](https://howtodoinjava.com/java/collections/java-arrayblockingqueue/)

`ArrayBlockingQueue`类是由数组支持的 Java **并发**和**有界**阻塞队列实现。 它对元素 FIFO（先进先出）进行排序。

`ArrayBlockingQueue`的**头部**是已在队列中最长时间的元素。 `ArrayBlockingQueue`的**尾部**是已在队列中最短时间的元素。 将新的**元素插入到队列的末尾**，并且队列**检索操作将在队列的头**获得元素。

## 1\. `ArrayBlockingQueue`特性

让我们记下`ArrayBlockingQueue`类的几个要点。

*   `ArrayBlockingQueue`是由数组支持的固定大小的有界队列。
*   它对元素 FIFO（先进先出）进行排序。
*   元素插入到尾部，并从队列的开头检索。
*   创建后，队列的容量无法更改。
*   它提供**阻塞插入和检索操作**。
*   它不允许使用`NULL`对象。
*   `ArrayBlockingQueue`是**线程安全的**。
*   方法`iterator()`中提供的`Iterator`从第一个（头）到最后一个（尾）顺序遍历元素。
*   `ArrayBlockingQueue`支持可选的**公平性策略**，用于顺序等待的生产者线程和使用者线程。 公平设置为`true`时，队列以 FIFO 顺序授予线程访问权限。

## 2\. Java `ArrayBlockingQueue`示例

#### 2.1 `ArrayBlockingQueue`阻塞插入和检索示例

使用阻塞插入和检索从`ArrayBlockingQueue`中放入和取出元素的 Java 示例。

*   当队列已满时，生产者线程将等待。 一旦从队列中取出一个元素，它就会将该元素添加到队列中。
*   如果队列为空，使用者线程将等待。 队列中只有一个元素时，它将取出该元素。

Java 数组阻塞队列生产者使用者示例。

```java
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

public class ArrayBlockingQueueExample 
{
    public static void main(String[] args) throws InterruptedException 
    {
        ArrayBlockingQueue<Integer> priorityBlockingQueue = new ArrayBlockingQueue<>(5);

        //Producer thread
        new Thread(() -> 
        {
            int i = 0;
            try 
            {
                while (true) 
                {
                    priorityBlockingQueue.put(++i);
                    System.out.println("Added : " + i);

                    Thread.sleep(TimeUnit.SECONDS.toMillis(1));
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }).start();

        //Consumer thread
        new Thread(() -> 
        {
            try 
            {
                while (true) 
                {
                    Integer poll = priorityBlockingQueue.take();
                    System.out.println("Polled : " + poll);

                    Thread.sleep(TimeUnit.SECONDS.toMillis(2));
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }).start();
    }
}

```

程序输出。

```java
Added : 1
Polled : 1
Added : 2
Polled : 2
Added : 3
Added : 4
Polled : 3
Added : 5
Added : 6
Polled : 4
Added : 7
Added : 8
Polled : 5
Added : 9

```

## 3\. Java `ArrayBlockingQueue`构造器

`ArrayBlockingQueue`类提供了 3 种不同的方法来用 Java 构造队列。

*   **`ArrayBlockingQueue(int Capacity)`**：构造具有给定（固定）容量和默认访问策略的空队列。
*   **`ArrayBlockingQueue(int capacity, boolean fair)`**：构造具有给定（固定）容量和指定访问策略的空队列。 如果公允值为`true`，则按 FIFO 顺序处理对在插入或拔出时阻塞的线程的队列访问； 如果为`false`，则未指定访问顺序。
*   **`ArrayBlockingQueue(int capacity, boolean fair, Collection c)`**：构造一个具有给定（固定）容量，指定访问策略并最初包含给定集合元素的队列，并按集合的遍历顺序添加迭代器。

## 4\. Java `ArrayBlockingQueue`方法

您应该知道`ArrayBlockingQueue`类具有以下给定的重要方法。

*   **`void put(Object o)`**：将指定的元素插入此队列的尾部，如果队列已满，则等待空间变为可用。 
*   **`boolean add(object)`**：如果可以在不超出队列容量的情况下立即执行此操作，则在此队列的末尾插入指定的元素，如果队列已满，则返回`true`，并抛出`IllegalStateException`。
*   **`boolean offer(object)`**：如果可以在不超过队列容量的情况下立即执行此操作，则在此队列的末尾插入指定的元素，如果队列已满，则返回`true`，并抛出`IllegalStateException`。
*   **`boolean remove(object)`**：从此队列中移除指定元素的单个实例（如果存在）。
*   **`Object peek()`**：检索但不删除此队列的头，如果此队列为空，则返回`null`。
*   **`Object poll()`**：检索并删除此队列的头部，如果此队列为空，则返回`null`。
*   **`Object poll(timeout, timeUnit)`**：检索并删除此队列的开头，并在必要时等待指定的等待时间以使元素可用。
*   **`Object take()`**：检索并删除此队列的头，如有必要，请等待直到元素可用。
*   **`void clear()`**：从此队列中删除所有元素。
*   **`boolean contains(Object o)`**：如果此队列包含指定的元素，则返回`true`。
*   **`Iterator iterator()`**：按适当的顺序返回此队列中元素的迭代器。
*   **`int size()`**：返回此队列中的元素数。
*   **`intrainToTo(Collection c)`**：从此队列中删除所有可用元素，并将它们添加到给定的集合中。
*   **`intrainTo(Collection c, int maxElements)`**：从此队列中最多移除给定数量的可用元素，并将其添加到给定的集合中。
*   **`int remainingCapacity()`**：返回此队列理想情况下（在没有内存或资源约束的情况下）可以接受而不阻塞的其他元素的数量。
*   **`Object[] toArray()`**：按正确的顺序返回包含此队列中所有元素的数组。

## 5\. 总结

在此 **Java `ArrayBlockingQueue`教程**中，我们学习了使用`ArrayBlockingQueue`类，该类能够将元素存储在固定大小的**并发阻塞队列中**。

我们还学习了`ArrayBlockingQueue`类的一些重要方法和[构造器](https://howtodoinjava.com/oops/java-constructors/)。

将我的问题放在评论部分。

学习愉快！

参考文献：

[`ArrayBlockingQueue`类 Java 文档](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayBlockingQueue.html)