К
Канал Андрея про бекенд
@andrey_threads1.7K подп.
3.3Kпросмотров
26 марта 2025 г.
Score: 3.6K
Аналог блокирующей очереди для корутин ⛓ В одном из предыдущих&nbsp;постов мы обсуждали удобство использования блокирующий очереди (интерфейс java.util.concurrent.BlockingQueue), для коммуникации между потоками. Одна группа потоков помещают данные в хвост очереди, другая группа получает данные из ее головы. Почему бы нам не использовать такую же очередь для общения корутин друг с другом? 🏈 Дело в том, что операции BlockingQueue&nbsp;могут заблокировать&nbsp;поток исполнения: - Получение элемента блокируется, если очередь пуста - Вставка в очередь может блокироваться, если максимальный размер очереди уже достигнут 🧨 Но использовать внутри корутин операции, блокирующие поток, антипаттерн. Поэтому, например, существует отдельный набор мьютексов, которые не блокируют поток, а реализуют взаимное исключение именно для корутин. 🥁 Есть ли неблокирующий аналог для BlockingQueue&nbsp;в мире корутин? Да, интерфейс kotlinx.coroutines.channels.Channel&nbsp;и его реализации концептуально являются воплощениями блокирующей очереди. "Канал" предоставляет методы send&nbsp;и receive, которые тоже обладают блокирующей семантикой, но блокируют они корутину, а не поток, на котором она исполняется. ✍️ Как и очередь, ченнел может иметь ограниченный размер буфера элементов. Вы можете определить его, передав в конструктор. Но есть специальные, зарезервированные значения длины буфера, в зависимости от которых вам будет предоставлена наиболее оптимальная реализация канала. Например, в качестве размера вы можете передать следующие константы: 1. Channel.RENDEZVOUS:&nbsp;в этом случае вам будет создан канал не имеющий никакого буфера. Каждый вызов метода send&nbsp;будет блокировать корутину, пока на встречу (на рандеву) с ним не придет соответствующий метод receive. 2. Channel.UNLIMITED:&nbsp;тут все понятно, буфер будет “бесконечным”, что фактически можно читать, как “сколько памяти хватит”. Метод send&nbsp;в этой реализации не заблокирует корутину никогда. 3. Channel.CONFLATED:&nbsp;довольно интересная реализация канала. Поддерживает буфер размером в один элемент. Каждый последний вызов метода send&nbsp;подменяет то, что было записано ранее. Метод receive&nbsp;соответственно всегда прочитает последнее записанное значение. Как и в прошлом пункте метод send&nbsp;никогда не блокируется. Создание ченнела&nbsp;с размером буфера равным десяти, запись и чтение из него: val channel = Channel<Element>(capacity) // Producer code channel.send(elementToSend) // Consumer code val elementReceived = channel.receive() Ставьте 🔥, если было полезно и отвечайте на опрос ниже ⬇️ #kotlin&nbsp;#coroutines
3.3K
просмотров
2624
символов
Да
эмодзи
Нет
медиа

Другие посты @andrey_threads

Все посты канала →
Аналог блокирующей очереди для корутин ⛓ В одном из предыдущ — @andrey_threads | PostSniper