Типы каналов: Rendezvous, Buffered, Conflated, Unlimited
Выбирайте подходящий тип канала для используемой схемы взаимодействия.
«Типы каналов: Rendezvous, Buffered, Conflated, Unlimited» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.
Создание каналов
Создавайте каналы с помощью Channel<T>(capacity). Ёмкость определяет поведение буферизации и приостановки.
import kotlinx.coroutines.channels.Channel
val rendezvous = Channel<Int>() // capacity 0
val buffered = Channel<Int>(64) // capacity 64
val unlimited = Channel<Int>(Channel.UNLIMITED)
val conflated = Channel<Int>(Channel.CONFLATED)
fun main() { println("Channel types created") }Встречный канал (ёмкость = 0)
Канал по умолчанию. send приостанавливается, пока не будет готов получатель, а receive — пока отправитель не отправит значение. Они встречаются в одной точке.
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
val ch = Channel<Int>() // rendezvous
launch {
println("Sending...")
ch.send(1) // suspends until receiver is ready
println("Sent")
}
delay(100)
println("Receiving...")
println(ch.receive())
}Буферизованный канал
Буферизованный канал позволяет отправителю продолжать работу, не ожидая, пока буфер не заполнится. Когда буфер заполнен, send приостанавливается.
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
val ch = Channel<Int>(3) // buffer of 3
launch {
repeat(3) {
println("Sending $it")
ch.send(it) // does not suspend until buffer full
}
ch.close()
}
delay(500)
for (v in ch) println("Got $v")
}Буферизованный канал по умолчанию
Channel.BUFFERED использует ёмкость по умолчанию — 64. Это эквивалентно Channel(64).
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.*
fun main() = runBlocking {
val ch = Channel<String>(Channel.BUFFERED)
println("Default buffer capacity is implementation-defined (~64)")
ch.close()
}Неограниченный канал
Channel.UNLIMITED никогда не приостанавливает отправителя: он буферизует все значения. Используйте его осторожно: память может расти без ограничений.
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
val ch = Channel<Int>(Channel.UNLIMITED)
launch {
repeat(1000) { ch.send(it) } // never suspends
ch.close()
}
var sum = 0
for (v in ch) sum += v
println("Sum: $sum")
}Канал с сохранением последнего значения
Channel.CONFLATED сохраняет только самое новое значение. Если новое значение поступает до получения предыдущего, старое отбрасывается.
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
val ch = Channel<Int>(Channel.CONFLATED)
launch {
repeat(5) { ch.send(it) } // 0..4 sent rapidly
ch.close()
}
delay(50) // let all sends happen
println("Received: ${ch.tryReceive().getOrNull()}") // likely 4 (last)
}RENDEZVOUS и BUFFERED: синхронизация по времени
RENDEZVOUS синхронизирует производителя и потребителя. BUFFERED позволяет производителю работать с опережением, разделяя их временные характеристики.
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
val ch = Channel<Int>(Channel.BUFFERED)
val t = System.currentTimeMillis()
launch {
repeat(5) { ch.send(it) } // fast — doesn't wait
ch.close()
}
for (v in ch) { delay(100); println("$v at ${System.currentTimeMillis()-t}ms") }
}Стратегия onBufferOverflow
С помощью Channel(capacity, onBufferOverflow) выберите поведение при заполнении буфера: приостановка по умолчанию, отбрасывание самых старых значений или отбрасывание самых новых.
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
val ch = Channel<Int>(2, BufferOverflow.DROP_OLDEST)
launch {
repeat(5) { ch.trySend(it) } // 0,1,2,3,4 — buffer keeps newest 2
ch.close()
}
for (v in ch) println(v) // likely 3 4
}Выбор типа канала
Руководство: RENDEZVOUS — для тесной синхронизации; BUFFERED — для пропускной способности; CONFLATED — когда нужно только последнее значение, например состояние интерфейса; UNLIMITED — для журналирования событий, если потеря данных недопустима.
import kotlinx.coroutines.channels.Channel
// Use cases:
// RENDEZVOUS — handshake between producer and consumer
// BUFFERED — decouple I/O-heavy producer from slow consumer
// CONFLATED — UI updates (only latest matters)
// UNLIMITED — audit log (never drop)
fun main() { println("Choose based on your loss tolerance and timing needs") }Каналы в конструкции выбора
select позволяет одновременно ожидать несколько каналов, выбирая первый готовый.
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.selects.*
fun main() = runBlocking {
val a = produce { delay(100); send("from a") }
val b = produce { delay(50); send("from b") }
val result = select<String> {
a.onReceive { it }
b.onReceive { it }
}
println(result) // "from b"
coroutineContext.cancelChildren()
}Канал-таймер
ticker(delay) создаёт канал, который выдаёт Unit каждые delay миллисекунд. Это полезно для повторяющегося опроса.
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
fun main() = runBlocking {
val ticker = ticker(delayMillis = 100, initialDelayMillis = 0)
var count = 0
for (tick in ticker) {
println("Tick ${++count}")
if (count == 3) { ticker.cancel(); break }
}
}Быстрая проверка
Какой тип канала сохраняет только самое новое значение?
Итоги
Встречный канал: синхронизация без буфера. Буферизованный канал: разделение временных характеристик. Канал с сохранением последнего значения: только новое значение, старые отбрасываются. Неограниченный канал: отправитель никогда не приостанавливается. Выбирайте тип с учётом допустимости потерь и требований к пропускной способности.
Часто задаваемые вопросы
Урок «Типы каналов: Rendezvous, Buffered, Conflated, Unlimited» бесплатный?
Да — полный текст урока «Типы каналов: Rendezvous, Buffered, Conflated, Unlimited» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.
Чему я научусь в уроке «Типы каналов: Rendezvous, Buffered, Conflated, Unlimited»?
Выбирайте подходящий тип канала для используемой схемы взаимодействия. Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Kotlin Academy?
Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Типы каналов: Rendezvous, Buffered, Conflated, Unlimited»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Kotlin Academy?
Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Основы каналов: send, receive и close
- Типы каналов: Rendezvous, Buffered, Conflated, Unlimited
- Mutex и Semaphore для общего состояния
- Акторы и структурированное управление состоянием