Освоение Java LinkedBlockingQueue: полное руководство и примеры
Java LinkedBlockingQueue
Изучите класс LinkedBlockingQueue, его основные методы и реальные примеры для разблокировки потокобезопасной очереди в Java.
Класс LinkedBlockingQueue, входящий в пакет java.util.concurrent Java, реализует блокирующую очередь на базе связного списка. Он соответствует интерфейсу BlockingQueue, предоставляя надёжную, потокобезопасную структуру для сценариев производитель-потребитель.
Создание LinkedBlockingQueue
Для использования этой очереди импортируйте java.util.concurrent.LinkedBlockingQueue:
import java.util.concurrent.LinkedBlockingQueue;
1. Без начальной ёмкости
LinkedBlockingQueue<Type> queue = new LinkedBlockingQueue<>();
Ёмкость по умолчанию — Integer.MAX_VALUE (231–1), делая очередь фактически неограниченной.
2. С указанной ёмкостью
LinkedBlockingQueue<Type> queue = new LinkedBlockingQueue<>(int capacity);
Type— тип элементов (например,String,Integer)capacity— максимальное количество элементов, которое может содержать очередь
Пример:
// Строковая очередь с ёмкостью 5
LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);
// Целочисленная очередь с ёмкостью 5
LinkedBlockingQueue<Integer> ages = new LinkedBlockingQueue<>(5);
Примечание: Ёмкость опциональна; её отсутствие создаёт неограниченную очередь.
Ключевые методы LinkedBlockingQueue
Класс реализует все методы BlockingQueue, позволяя вставку, извлечение и удаление элементов. Два метода — put() и take() — предоставляют блокирующее поведение, отличающее эту очередь от стандартных.
Вставка элементов
add(E e)— добавляет элемент, выбрасывая исключение, если очередь полна.offer(E e)— добавляет элемент, возвращаяfalse, если очередь полна.
Пример:
import java.util.concurrent.LinkedBlockingQueue;
public class Main {
public static void main(String[] args) {
LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);
animals.add("Dog");
animals.add("Cat");
animals.offer("Horse");
System.out.println("LinkedBlockingQueue: " + animals);
}
}
Вывод
LinkedBlockingQueue: [Dog, Cat, Horse]
Доступ к элементам
peek()— получает, но не удаляет головной элемент; возвращаетnull, если пуста.iterator()— предоставляет fail-safe итератор по очереди. Импортируйтеjava.util.Iteratorдля использования.
Пример:
import java.util.concurrent.LinkedBlockingQueue;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);
animals.add("Dog");
animals.add("Cat");
animals.add("Horse");
System.out.println("LinkedBlockingQueue: " + animals);
String head = animals.peek();
System.out.println("Accessed Element: " + head);
Iterator<String> it = animals.iterator();
System.out.print("LinkedBlockingQueue Elements: ");
while (it.hasNext()) {
System.out.print(it.next() + ", ");
}
}
}
Вывод
LinkedBlockingQueue: [Dog, Cat, Horse] Accessed Element: Dog LinkedBlockingQueue Elements: Dog, Cat, Horse,
Удаление элементов
remove()— удаляет и возвращает голову; выбрасывает исключение, если пуста.poll()— удаляет и возвращает голову; возвращаетnull, если пуста.clear()— удаляет все элементы.
Пример:
import java.util.concurrent.LinkedBlockingQueue;
public class Main {
public static void main(String[] args) {
LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);
animals.add("Dog");
animals.add("Cat");
animals.add("Horse");
System.out.println("LinkedBlockingQueue: " + animals);
String removed = animals.remove();
System.out.println("Using remove(): " + removed);
String polled = animals.poll();
System.out.println("Using poll(): " + polled);
animals.clear();
System.out.println("Updated LinkedBlockingQueue: " + animals);
}
}
Вывод
LinkedBlockingQueue: [Dog, Cat, Horse] Using remove(): Dog Using poll(): Cat Updated LinkedBlockingQueue: []
Блокирующие операции: put() и take()
В параллельных контекстах put() и take() блокируют вызывающий поток до возможности выполнения операции, обеспечивая безопасную координацию между производителями и потребителями.
put()
Вставляет элемент в хвост, ожидая, если очередь полна.
Пример:
import java.util.concurrent.LinkedBlockingQueue;
public class Main {
public static void main(String[] args) {
LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);
try {
animals.put("Dog");
animals.put("Cat");
System.out.println("LinkedBlockingQueue: " + animals);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println(e.getMessage());
}
}
}
Вывод
LinkedBlockingQueue: [Dog, Cat]
take()
Извлекает и удаляет головной элемент, блокируя, если очередь пуста.
Пример:
import java.util.concurrent.LinkedBlockingQueue;
public class Main {
public static void main(String[] args) {
LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);
try {
animals.put("Dog");
animals.put("Cat");
System.out.println("LinkedBlockingQueue: " + animals);
String removed = animals.take();
System.out.println("Removed Element: " + removed);
System.out.println("New LinkedBlockingQueue: " + animals);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println(e.getMessage());
}
}
}
Вывод
LinkedBlockingQueue: [Dog, Cat] Removed Element: Dog New LinkedBlockingQueue: [Cat]
Дополнительные утилитарные методы
| Метод | Описание |
|---|---|
contains(Object o) | Проверяет, содержит ли очередь указанный элемент. |
size() | Возвращает текущее количество элементов. |
toArray() | Преобразует очередь в массив. |
toString() | Предоставляет строковое представление очереди. |
Зачем выбирать LinkedBlockingQueue?
Поскольку он использует связный список внутри, LinkedBlockingQueue предлагает:
- Потокобезопасность из коробки.
- Опциональную ограниченную ёмкость для контроля обратного давления.
- Блокирующие методы, естественно координирующие производителей и потребителей.
В многопоточных приложениях, где один поток может производить медленнее, чем другой потребляет, очередь автоматически приостановит потребителя до появления новых элементов, предотвращая занятое ожидание и снижая нагрузку на CPU.
Для высокопроизводительных параллельных нагрузок Java Concurrency API рекомендует LinkedBlockingQueue как структуру по умолчанию для конвейеров производитель-потребитель.
java
- Освоение операторов Java: типы, синтаксис и практические примеры
- Комментарии в Java: типы, использование и лучшие практики
- Освоение улучшенного цикла for в Java: синтаксис, примеры и лучшие практики
- Освоение строк в Java: создание, методы и лучшие практики
- Интерфейсы в Java: концепции, реализация и лучшие практики
- Анонимные внутренние классы в Java: определение, синтаксис и практические примеры
- Try-with-resources в Java: автоматическое управление ресурсами
- Аннотации в Java: типы, размещение и практические примеры
- Assertions в Java: практическое руководство по обнаружению багов и обеспечению надежности кода
- Понимание Java Vector: использование, особенности и сравнение с ArrayList