9. Channel(채널)이란?

thsamajiki·2023년 2월 18일
0

Coroutine

목록 보기
8/8

💡 Channel (채널)

채널은 일종의 파이프라인이다. 채널을 열고 한쪽에서 값을 보내면 다른 쪽에서 수신하는 개념이다.

기본적인 사용법

기본적인 사용법은 간단하다.

val channel = Channel<Int>()

CoroutineScope(Dispatchers.Default).launch {
    channel.send(it)
    channel.receive()
}

channel.close()

Channel<...>() 함수를 통해 생성할 수 있으며,

데이터를 스트림에 밀어 넣을 땐 send, 스트림에서 받을 땐 receive 를 사용하면 된다.

생성 위치는 상관없지만 send 와 receive 는 suspend 함수이기 때문에 코루틴 내부에서 호출되어야 한다.

채널에 더 이상 아무 데이터도 보내거나 받지 않는다면 채널을 종료시켜야 한다.

close 함수를 통해서 종료시킬 수 있으며,

종료 이후에 send, receive 함수는 ClosedReceiveChannelException 을 발생시킨다.



파이프라인

파이프라인은 채널을 생성하는 패턴으로

하나의 코루틴이 초기 데이터를 생성하고, 소비하는 곳에서 받은 후 새로운 데이터를 생성하는 흐름을 말한다.
유한 또는 무한 개의 값을 만드는 코루틴.

produce<...>{ ... } 함수를 통하여 만들 수 있다.

val numbers = produce<Int> { for (x in 0 .. Int.MAX_VALUE) send(x) }
val numXnum = produce { for (x in numbers) send(x * x) }

사용법은 위와 같으며 결과물로는 0 ~ MAX_VALUE 까지 데이터를 방출하고 그 곱을 방출하는 채널이 만들어진다.

응답값으로 ReceiveChannel 가 반환되며, 해당 채널은 데이터를 추가적으로 보내는 것 ( send ) 은 불가능하고
produce 내부에서 생성된 데이터를 받는 거 ( receive ) 만 가능하다.

다음의 예제 코드를 보자.

val channel = Channel<Int>()

lifecycleScope.launch {
	repeat(5){
		channel.send(20 + it)
	}
}

lifecycleScope.launch {
	for(temperature in channel) {
		Log.d("TEST", "$temperature")
	}
}

이 코드를 실행하면 모두 받고 출력하는 이전 코드와 달리 값을 받을 때마다 출력해준다.

두 코루틴이 채널을 통해서 값을 주고 받을 수 있다. 채널에 send 메서드를 통해 값을 보내면 반대편에서 값을 받을 수 있다. 값을 받기 위해서는 receive 메서드를 받아야하는데 for in 문에서는 자동으로 값을 수신해서 전달해준다. for in은 채널이 닫힐 때까지 값을 받는다. 채널을 닫기 위해서는 명시적으로 close 메서드를 호출할 수 있다.

채널을 만들고 코루틴을 만들어서 값을 전달하는 과정은 반복적인 과정이다. 이 과정을 간단히 만들어주는 빌더 produce가 있다.

val channel = lifecycleScope.produce<Int>{
	repeat(5){
		channel.send(20 + it)
	}
}

lifecycleScope.launch {
	for(temperature in channel) {
		Log.d("TEST", "$temperature")
	}
}
profile
안드로이드 개발자

0개의 댓글