안녕하세요. 저는 Android를 개발하고있는 김재원이라고 합니다😃. 이번에 처음으로 블로그를 작성해보려고 하는데요, 저의 블로그가 많은분에게 도움이 되었으면 좋겠습니다😊.
우선 코루틴은 Kotlin에만 있는것이 아닙니다. 다른 언어에서도 지원하고 있는 개념이죠. 그렇다면 코루틴(coroutine)은 무엇일까.. 코루틴도 ReactiveX 와 같이 비동기처리를 도와주는 방법입니다. 하지만 차이점이 있다면 ReactiveX는 병렬성 프로그래밍 이고, 코루틴은 동시성프로그래밍 이라는점이죠.
루틴(routine) : 프로그램이 실행될때 호출되는 일련의 코드들 입니다.(함수 등)
동시성 프로그래밍은 하나의 스레드만를 사용해 비동기작업을 처리합니다.
예를 들어서 2장의 도화지에 각각 다른 그림을 그려야한다고 생각해봅시다.
이때 펜 하나만(스레드 하나)을 사용해서 왼쪽도화지에 조금그리고, 오른쪽도화지에 조금그리고. 다시 왼쪽, 오른쪽... 이런 루틴을 빠르게 하면 우리가 보기엔 도화지 두개에 동시에 그림이 그려지는것 처럼 보일것입니다. 이것이 동시성 프로그래밍입니다.
반대로 펜 두개를 사용해서 두 도화지에 실제로 동시에 그리는것이 병렬성 프로그래밍인것이죠🙂
최근 구글에서 코루틴을 많이 밀어준다는 말을 많이 들었습니다. 구글의 예제코드에 있는 RxJava들은 코루틴으로 리펙토링 되고 있는등, 정말로 코루틴이 대세입니다🤔.
그 이유엔 코루틴이 동시성 프로그래밍인 영향이 큽니다.
병렬성 프로그래밍은 여러개의 스레드를 사용합니다. 하지만 CPU는 하나이죠. 그래서 CPU가 매번 스레드를 점유했다 놓았다를 반복하는데 이를 컨텍스트 스위칭(문맥교환)이라고 합니다. 이는 꽤 많은 비용이 드는 작업입니다.
반대로 동시성 프로그래밍은 스레드를 교환하는것 보다 가볍게 하나의 스레드 안에서 루틴들을 교환하기 때문에 자원낭비가 덜하다는 장점이 있죠🙂.
아래는 '함수형 코틀린'이라는 책에나온 구문중 일부입니다.
이런 코루틴의 특징때문에 코틀린에는 suspend 함수가 있는것 입니다. suspend는 멈추다 라는 뜻입니다. suspend함수는 멈춰두고 다른 함수를 실행한 후 다시 돌아와서 실행 할 수 있기 때문에 정말 딱 알맞는 함수이름인것 같습니다😮.
suspend함수는 일반함수에서 호출하면 안됩니다.
IDE에서 이렇게 빨간줄으로 경고를 합니다
경고메시지를 읽어보면 coroutine에서나 다른 suspend함수에서 호출 해야한다고 되어있습니다. 일반함수(위의 코드에서 main)는 함수를 마음대로 진입, 탈출할 자격이 없기때문인데요. 코루틴을 시작하는 함수는 다음과 같이 2개가 있습니다.
fun main() {
CoroutineScope(Dispatchers.IO).launch {
testSuspendFun()
}
}
fun main() {
val result = CoroutineScope(Dispatchers.IO).async {
iWillReturnString()
}
print(result)
}
suspend fun iWillReturnString():String {
delay(2000)
return "result"
}
위에있는 예시코드에서 coroutine scope가 있었습니다. coroutine scope는 launch 혹은 async로 만들어진 coroutine을 추적합니다. 그래서 실행중인 코루틴은 언제든 scope.cancel()을 호출하여 취소할 수 있는거죠🙂.
fun main() {
val coroutineScope = CoroutineScope(Dispatchers.IO)
val result = coroutineScope.async {
iWillReturnString()
}
print(result)
coroutineScope.cancel()
}
Android에서는 특정 생명주기에 맞춰서 scope를 제공합니다. viewModelScope가 그 대표적인 예 입니다.
Dispatcher은 코루틴을 어떤 스레드에서 실행시킬 지 결졍합니다. kotlin은 다음 3가지 dispatcher을 제공합니다.
Dispatcher.Main : Android 기본 스레드에서 코루틴을 실행합니다. Ui와의 상호작용시에만 사용합니다.
Dispatcher.IO : 기본 스레드 외부에서 디스크 혹은 네트워크를 통한 입/출력에 최적화 되어있습니다. 주로 로컬 데이터를 읽고 쓸데나, 네트워크 통신을 할때 사용합니다.
Dispatcher.Detault : CPU를 많이 사용하는 작업을 기본 스레드 외부에서 실행합니다. 예를 들어 Json 파싱등이 있습니다.
이렇게 해서 코틀린 코루틴에 대해서 알아보았는데요, 다음글에서는 flow 등에 대해서 알아보도록 하겠습니다. 즐거운 개발 되세요~⚡️⚡️
참조
코틀린 코루틴(coroutine) 개념 익히기
코틀린 코루틴(Coroutine) 기초
Kotlin 코루틴으로 앱 성능 향상