채널 기초
예제 80: 채널
채널은 일종의 파이프입니다. 송신측에서 채널에 send
로 데이터를 전달하고 수신 측에서 채널을 통해 receive
받습니다. (trySend
와 tryReceive
도 있습니다. 과거에는 null
을 반환하는 offer
와 poll
가 있었습니다.)
예제 81: 같은 코루틴에서 채널을 읽고 쓰면?
send
나 receive
가 suspension point이고 서로에게 의존적이기 때문에 같은 코루틴에서 사용하는 것은 위험할 수 있습니다.
무한으로 대기하는 것을 볼 수 있습니다.
예제 82: 채널 close
채널에서 더 이상 보낼 자료가 없으면 close
메서드를 이용해 채널을 닫을 수 있습니다. 채널은 for in 을 이용해서 반복적으로 receive
할 수 있고 close
되면 for in은 자동으로 종료됩니다.
예제 83: 채널 프로듀서
생산자(producer)와 소비자(consumer)는 굉장히 일반적인 패턴입니다. 채널을 이용해서 한 쪽에서 데이터를 만들고 다른 쪽에서 받는 것을 도와주는 확장 함수들이 있습니다.
produce
코루틴을 만들고 채널을 재공합니다.consumeEach
채널에서 반복해서 데이터를 제공합니다.
ProducerScope
는 CoroutineScope
인터페이스와 SendChannel
인터페이스를 함께 상속받습니다. 그래서 코루틴 컨텍스트와 몇가지 채널 인터페이스를 같이 사용할 수 있는 특이한 스코프입니다.
produce
를 사용하면 ProducerScope
를 상속받은 ProducerCoroutine
코루틴을 얻게 됩니다.
참고:
우리가 흔히 쓰는 runBlocking
은 BlockingCoroutine
을 쓰는데 이는 AbstractCoroutine
를 상속받고 있어요.
결국 코루틴 빌더는 코루틴을 만드는데 이들이 코루틴 스코프이기도 한거죠.
AbstractCoroutine
은 JobSupport
, Job
(인터페이스), Continuation
(인터페이스), CoroutineScope
(인터페이스)을 상속받고 있고요.
Continuation
은 다음에 무엇을 할지, Job
은 제어를 위한 정보와 제어, CoroutineScope
는 컨텍스트 제공의 역할을 합니다. JobSupport
는 잡의 실무(?)를 한다고 봐야죠.
produce
파트를 함수로 분리해봅시다.suspend
함수와CoroutineScope
의 확장 함수의 방식을 해봅시다. (produce
는CoroutineScope
의 확장 함수)