Класс ArrayBlockingQueue — это реализация Java-блокировки с параллельным доступом и ограниченной блокировкой, поддерживаемая массивом. Он упорядочивает элементы FIFO(первым пришел — первым вышел).
Голова ArrayBlockingQueue — это элемент, который находится в очереди дольше всего. Хвост ArrayBlockingQueue — это элемент, который находится в очереди меньше всего. Новые элементы вставляются в конец очереди, а операции извлечения из очереди получают элементы из головы очереди.
1. Особенности ArrayBlockingQueue
Давайте отметим несколько важных моментов в классе ArrayBlockingQueue.
- ArrayBlockingQueue — это ограниченная очередь фиксированного размера, поддерживаемая массивом.
- Элементы упорядочены по принципу FIFO(первым пришел — первым ушел).
- Элементы вставляются в конец и извлекаются из начала очереди.
- После создания вместимость очереди изменить нельзя.
- Обеспечивает блокировку операций вставки и извлечения.
- Не допускается наличие объектов NULL.
- ArrayBlockingQueue является потокобезопасным.
- Итератор, представленный в методе iterator(), обходит элементы в порядке от первого(голова) до последнего(хвост).
- Он поддерживает опциональную политику справедливости для упорядочивания ожидающих потоков производителя и потребителя. Если справедливость установлена в значение true, очередь предоставляет потокам доступ в порядке FIFO.
2. Пример Java ArrayBlockingQueue
Ниже приведен пример помещения и извлечения элементов из ArrayBlockingQueue с использованием блокирующих вставок и извлечения.
- Поток-производитель будет ждать, пока очередь не заполнится. Как только элемент будет взят из очереди, он добавляет его в очередь.
- Потребительский поток будет ждать, если очередь пуста. Как только в очереди появляется один элемент, он извлекает его.
Пример поставщика-потребителя очереди блокировки массива 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 threadnew 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 threadnew 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();}}
Вывод программы.
Added : 1Polled : 1Added : 2Polled : 2Added : 3Added : 4Polled : 3Added : 5Added : 6Polled : 4Added : 7Added : 8Polled : 5Added : 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 в случае успеха и false, если очередь заполнена.
- boolean remove(object): Удаляет один экземпляр указанного элемента из этой очереди, если он присутствует.
- Object peek(): извлекает, но не удаляет, заголовок этой очереди или возвращает null, если эта очередь пуста.
- Object poll(): извлекает и удаляет заголовок этой очереди или возвращает null, если эта очередь пуста.
- Object poll(timeout, timeUnit): извлекает и удаляет заголовок этой очереди, ожидая в течение указанного времени ожидания, если это необходимо для того, чтобы элемент стал доступен.
- Object take(): извлекает и удаляет главу этой очереди, при необходимости ожидая, пока элемент станет доступным.
- void clear(): удаляет все элементы из этой очереди.
- boolean contains(Object o): Возвращает true, если эта очередь содержит указанный элемент.
- Итератор iterator(): возвращает итератор по элементам в этой очереди в правильной последовательности.
- int size(): возвращает количество элементов в этой очереди.
- int drainTo(Collection c) : удаляет все доступные элементы из этой очереди и добавляет их в указанную коллекцию.
- int drainTo(Collection c, int maxElements): удаляет не более указанного количества доступных элементов из этой очереди и добавляет их в указанную коллекцию.
- int remainCapacity(): возвращает количество дополнительных элементов, которые эта очередь может в идеале(при отсутствии ограничений памяти или ресурсов) принять без блокировки.
- Object[] toArray() : возвращает массив, содержащий все элементы в этой очереди в правильной последовательности.
5. Заключение
В этом уроке по Java ArrayBlockingQueue мы научились использовать класс ArrayBlockingQueue, который способен хранить элементы в параллельной блокирующей очереди фиксированного размера.
Мы также изучили несколько важных методов и конструкторов класса ArrayBlockingQueue.