Kotlin Coroutine 동작을 이해해보기 - Coroutine 이란?
Android 개발을 시작 했을 때, 저는 rxJava를 이용해 서버 통신 등 비동기 프로그래밍을 수행했었습니다. 그런데, 이제는 명백히 flow와 Coroutine이 대세가 된 것을 느낄 수 있습니다 (공식 문서, 컨퍼런스 등등).
이처럼 안드로이드 개발과 Kotlin이 떨어질 수 없게 되면서 Coroutine 또한 당연하게 사용법을 알아야만 했습니다.
그런데, 정작 Coroutine의 Android에서 사용법 (viewModelScope, lifecycleScope.launch 와 같이...)만 알 뿐, Coroutine의 원리는 무엇인지에 대해 깊이 고민해 볼 시간을 가지지 않았습니다. 이에 반성하여, 자세하게 코루틴이 어떻게 동작하는지도 공부해보았습니다.
----------
장점?
먼저 Coroutine을 사용함에 있어 장점은 무엇일까요?
아까 말했듯, 저는 rxJava를 사용해서 비동기 프로그래밍을 구성했었는데요, 이를 언어적 차원에서도 지원한다는 점입니다. 즉 외부 라이브러리의 도움 없이도 비동기 통신을 보다 쉽게 구현할 수 있다는 점입니다. 이는, 클린 아키텍처를 사용하며, domain layer에서 외부 라이브러리 사용 없이 깔끔하게 의존성 관리 또한 용이합니다.
또한, 이미 많은 업데이트를 통해 안드로이드 친화적으로 위와 같이 lifecycleScope, viewModelScope 등을 편리하게 사용할 수 있다는 점도 장점이라고 볼 수 있습니다.
그리고, 이전 포스트에서 설명했듯 쓰레드보다 더 적은 리소스를 사용합니다.
사실 이 외에도 정말 많은 장점이 있겠지만, 여기까지만 작성해도 충분히 코루틴을 사용해야 할 이유로는 충분한 것 같습니다.
----------
Coroutine?
먼저 코루틴을 가장 기초부터 공부하기에는 https://kotlinlang.org/docs/coroutines-guide.html#additional-references , 코틀린의 공식 문서를 보면 좋습니다.
다만 보라고만 하고, 아무얘기 안하면... 포스트가 아니니까 조금 더 쉽고 딥하게 알아보겠습니다.
참고로, Coroutine은 코틀린만의 고유 기술? 기능? 이 아닙니다. 아래 예시와 같이, 흐름을 설명하는 단어일 뿐입니다. 파이썬에도 코루틴은 있습니다.
보통 우리가 작성하는 코드는 main 함수에서 시작하게 됩니다.
그리고, 함수에 진입하게 되면 함수안의 내용들을 수행하고 return을 만나서 다시 main 함수로 돌아오게 됩니다.
여기서 main 함수를 메인 루틴, plusOne이라는 함수가 서브 루틴이라고 불립니다.
이 코드는 당연하고 모두들 알고 있는 동기적인 코드이지만, 문제점이 있습니다. 만약 plusOne이라는 함수 안에서, 즉 서브 루틴에서 엄청나게 오래 걸리는 프로세스가 있다면 어떻게 될까요? 프로그램은 해당 프로세스를 마칠 때 까지 메인 루틴을 실행시킬 수 없어 그대로 멈춰있게 됩니다. 특히나 Android에서는 5초란 시간을 메인 쓰레드를 점유하고 있다면, 모두들 호달달 무서워 하는 ANR을 마주치게 됩니다.
이처럼 서브 루틴이 끝나는걸 기다리지 않고, 특정 함수를 만나서 서브 루틴을 나왔다가, 다시 들어가고를 반복할 수 있는 것을 우리가 공부하고 있는 코루틴이라고 합니다.
즉, 서버 통신에 5초가 걸려도(TimeOut에 걸리지 않는다고 했을 때) 프로그램이 멈춰있지 않고 계속해서 사용자와 Interaction이 가능하다는 뜻입니다.
---------
그래서 궁금했던건...
저는 그런데 궁금했습니다. 어떻게 Coroutine을 사용하면서 서버에서 응답이 오면, 다시 코루틴 블록으로 돌아와 실행이 되는걸까?
이에 대한 해답은, Corotuine Continuation에 있습니다.
이에 대해서 설명하기 위해서 CPS Style, Coroutine Continuation, JVM 메모리 구조 모두 섞어서 설명하려 하기 때문에, 다음 포스트에서 이어서 설명하겠습니다 (절대...시간이 없어서 그런거 아님)
참고 및 추천 블로그