Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Queue: назначение и использование
Queue (очередь) — это структура данных, которая реализует принцип FIFO (First-In-First-Out). Она используется для упорядочивания обработки элементов в порядке их поступления, что критично для многих real-world приложений.
Основной принцип FIFO
// Queue работает по принципу FIFO
// Первый поступивший элемент — первый обработанный
Queue<String> queue = new LinkedList<>();
// Добавление (enqueue)
queue.add("first"); // Добавляем в конец
queue.add("second");
queue.add("third");
// Удаление/получение (dequeue)
String first = queue.poll(); // Удаляет из начала -> "first"
String second = queue.poll(); // -> "second"
String third = queue.poll(); // -> "third"
Интерфейс Queue
// Queue предоставляет два способа работы с элементами
// Способ 1: Методы, выбрасывающие исключения
Queue<Integer> queue1 = new LinkedList<>();
queue1.add(1); // Добавить (выбросит исключение если очередь полна)
queue1.remove(); // Удалить (выбросит исключение если очередь пуста)
queue1.element(); // Получить без удаления (выбросит исключение если пуста)
// Способ 2: Методы, возвращающие null или false
Queue<Integer> queue2 = new LinkedList<>();
queue2.offer(1); // Добавить (вернёт false если полна)
queue2.poll(); // Удалить (вернёт null если пуста)
queue2.peek(); // Получить (вернёт null если пуста)
Практическое применение
1. Обработка задач (Task Processing)
public class TaskProcessor {
private Queue<Task> taskQueue = new LinkedList<>();
public void submitTask(Task task) {
taskQueue.offer(task); // Добавляем в очередь
}
public void processTasks() {
while (!taskQueue.isEmpty()) {
Task task = taskQueue.poll(); // Берём из очереди
if (task != null) {
task.execute();
}
}
}
}
class Task {
private String name;
public Task(String name) {
this.name = name;
}
public void execute() {
System.out.println("Выполняю: " + name);
}
}
// Использование
TaskProcessor processor = new TaskProcessor();
processor.submitTask(new Task("Отправить email"));
processor.submitTask(new Task("Сохранить файл"));
processor.submitTask(new Task("Обновить БД"));
processor.processTasks();
2. Буферизация между быстрым и медленным потребителем
public class ProducerConsumer {
private BlockingQueue<Data> buffer = new LinkedBlockingQueue<>(100);
// Быстрый производитель
public void produce() {
for (int i = 0; i < 1000; i++) {
try {
buffer.put(new Data(i)); // Блокирует если очередь полна
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
// Медленный потребитель
public void consume() {
for (int i = 0; i < 1000; i++) {
try {
Data data = buffer.take(); // Ждёт если очередь пуста
slowProcess(data);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
private void slowProcess(Data data) {
try { Thread.sleep(100); } catch (Exception e) {}
}
}
3. Обработка запросов в веб-сервере
public class WebServer {
private BlockingQueue<HttpRequest> requestQueue =
new LinkedBlockingQueue<>(1000);
private ExecutorService workerThreads =
Executors.newFixedThreadPool(10);
// Принимаем входящие запросы
public void acceptRequest(HttpRequest request) {
try {
requestQueue.put(request); // Добавляем в очередь
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// Worker потоки обрабатывают запросы по очереди
public void start() {
for (int i = 0; i < 10; i++) {
workerThreads.submit(() -> {
while (true) {
try {
HttpRequest request = requestQueue.take();
handleRequest(request);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
}
}
private void handleRequest(HttpRequest request) {
// Обработка запроса
}
}
4. Message Queue для асинхронной обработки
// Имитация message broker (как RabbitMQ или Kafka)
public class SimpleMessageBroker {
private BlockingQueue<Message> messageQueue =
new LinkedBlockingQueue<>();
// Publisher отправляет сообщения
public void publish(Message message) {
try {
messageQueue.put(message);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// Subscriber получает сообщения
public void subscribe(Consumer<Message> handler) {
new Thread(() -> {
while (true) {
try {
Message message = messageQueue.take();
handler.accept(message);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}).start();
}
}
Типы Queue
1. LinkedList (unbounded)
Queue<String> queue = new LinkedList<>();
// Не имеет максимального размера
// Может расти неограниченно
// Медленнее чем ArrayDeque в большинстве операций
2. ArrayDeque (double-ended deque)
Queue<String> queue = new ArrayDeque<>();
// Более быстрая чем LinkedList
// Unbounded
// Может работать как Deque (добавление с обоих концов)
3. BlockingQueue (потокобезопасная)
// LinkedBlockingQueue
BlockingQueue<String> queue = new LinkedBlockingQueue<>(100);
queue.put("item"); // Блокирует если полна
queue.take(); // Блокирует если пуста
// ArrayBlockingQueue
BlockingQueue<String> queue = new ArrayBlockingQueue<>(100);
// PriorityQueue (с приоритетами)
Queue<Task> queue = new PriorityQueue<>((t1, t2) ->
Integer.compare(t1.getPriority(), t2.getPriority())
);
Практический пример: Обработка уведомлений
public class NotificationService {
private BlockingQueue<Notification> notificationQueue =
new LinkedBlockingQueue<>();
// API получает уведомления
public void scheduleNotification(Notification notification) {
notificationQueue.offer(notification);
}
// Background поток отправляет уведомления
public void start() {
Thread sender = new Thread(() -> {
while (true) {
try {
Notification notification = notificationQueue.take();
sendNotification(notification);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
sender.setDaemon(true);
sender.start();
}
private void sendNotification(Notification notification) {
// Отправка email, SMS, push-уведомления и т.д.
System.out.println("Отправляю: " + notification.getMessage());
}
}
class Notification {
private String message;
private String recipient;
public Notification(String message, String recipient) {
this.message = message;
this.recipient = recipient;
}
public String getMessage() { return message; }
public String getRecipient() { return recipient; }
}
Преимущества Queue
- FIFO порядок — элементы обрабатываются в порядке поступления
- Decoupling — производитель и потребитель независимы
- Backpressure — BlockingQueue управляет нагрузкой
- Простота — интуитивный интерфейс
- Масштабируемость — легко добавить несколько потребителей
Когда использовать Queue
- Асинхронная обработка задач
- Балансировка нагрузки
- Буферизация между компонентами
- Очереди печати, почты, уведомлений
- Message brokers (RabbitMQ, Kafka)
- Thread pools и ExecutorService
Queue — это fundamental структура данных для построения масштабируемых и отзывчивых приложений.