- 코루틴끼리 통신을 위한 기본적인 방법으로 채널 API가 추가됨.
- 채널은 송신자와 수신자의 수에 제한이 없으며, 채널을 통해 전송된 모든 값은 단 한 번만 받을 수 있음.
채널(Channel)
- 두 개의 서로 다른 인터페이스를 구현한 하나의 인터페이스임.
SendChannel
은 원소를 보내거나(또는 더하거나) 채널을 닫는 용도로 사용됨.
ReceiveChannel
은 원소를 받을 때(또는 꺼낼 때)사용됨.
interface Channel<E> : SendChaanel<E>, ReceiveChannel<E>
interface SendChannel<in E> {
suspend fun send(element: E)
fun close(): Boolean
// ...
}
interface ReceiveChannel<out E> {
suspend fun receive(): E
fun cancel(cause: CancellationException> = null)
// ...
}
receive
를 호출했는데 채널에 원소가 없다면 코루틴은 원소가 들어올 때 까지 중단됨.
- 누군가 책을 찾으러 갔는데 책장이 비어 있는 경우, 다른 사람이 책을 넣을 때까지 기다려야함.
send
는 채널의 용량이 다 찼을 때 중단됨.
- 대부분의 채널은 용량이 제한되어 있음.
- 누군가 책을 넣으러 갔는데 책장이 가득 찬 경우, 다른 사람이 책을 가져가 공간이 생길 때까지 기다려야 함.
- 채널 양쪽 끝에 각각 하나의 코루틴만 있는 경우가 가장 일반적임.
- 수신자는 얼마나 많은 원소를 보내는지 알아야함.
- 송신자가 보내는 만큼 수신자가 기다리는 방식을 선호.
- 채널이 닫힐 때 까지 원소를 받기 위해
for loop
, consumeEach
함수를 사용할 수 있음.
- consumeEach
produce
함수는 빌더로 시작된 코루틴이 어떻게 종료되든 상관없이 채널을 닫음.
- 따라서 반드시
close
를 호출함.
produce
빌더는 채널을 만드는 가장 인기 있는 방법임. 안전하고 편리함.
suspend fun main(): Unit = coroutineScope {
val channel = produce {
repeat(5) { index ->
println("Producing next one")
delay(1000)
send(index * 2)
}
}
for (element in channel) {
println(element)
}
}
채널 타입
val channel = produce(capacity = Channel.XXX)
- 무제한 :
Channel.UNLIMITED
로 설정된 채널임. send
가 중단되지 않음.
- 채널은 모든 원소를 받고, 수신자가 하나씩 가져가게 함.
- 버퍼 :
Channel.BUFFERED
특정 용량 크기의 채널 타입임.
- 랑데뷰 :
Channel.RENDEZVOUS
용량이 0인 채널임. 송신자와 수신자가 만날 때만 원소를 교환함.
- 융합 :
Channel.CONFLATED
새로운 원소가 이전 원소를 대체함.