Введение в каналы в Kotlin
Корутины часто делят работу: одна готовит данные,
другая их обрабатывает. Канал в
kotlinx.coroutines.channels связывает такие
стороны: отправитель кладет значение, получатель
забирает его, а при необходимости ждет, пока
вторая сторона подойдет.
Канал создают вызовом Channel без аргументов.
Это очередь без запаса: лишнее значение в ней
не лежит.
Передача идет через send, прием через
receive; обе операции приостанавливают
корутину, если парная сторона еще не готова.
Простейшая схема - фоновая отправка строки и
ожидание ответа в том же runBlocking:
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
fun main() {
runBlocking {
val lane = Channel<String>()
launch {
lane.send("cargo")
}
val item = lane.receive()
println(item)
}
}
launch стартует передачу, receive
в родительской корутине забирает значение. Когда
обе стороны встретились, строка "cargo"
попадает в консоль. Блок runBlocking
не завершится, пока внутренний прием не закончится.
Порядок можно развернуть: сначала запускают получателя, затем отправителя. Канал без буфера все равно доставит одно значение ровно один раз:
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
fun main() {
runBlocking {
val lane = Channel<Int>()
launch {
val n = lane.receive()
println(n)
}
launch {
lane.send(9)
}
}
}
Число 9 печатает корутина-получатель.
Канал не хранит лишние копии: без буфера каждая
передача - это синхронная встреча отправителя и
получателя.