본문 바로가기
Study OR Book/코틀린 코루틴

[코틀린 코루틴] 1장 코틀린 코루틴을 배워야 하는 이유

by Baest 2025. 5. 20.

 

 

코틀린 코루틴을 배워야 하는 이유

- 이미 RxJava나 Refactor와 같은 JVM 계열 라이브러리가 있음

- 비동기적 연산을 수행하기 위한 다양한 방법이 존재

- 그럼에도 불구하고 코틀린 코루틴을 배워야하는 이유는 무엇일까

 

1963년 처음 제시되었으나 코루틴이라는 개념이 실제 현업에서 사용될 수 있도록 구현되기까지 수십 년 걸렸다.

 

 

멀티플랫폼에서 작동시킬 수 있고, 코틀린을 사용하는 모든 플랫폼을 넘나들며 사용할 수 있다.

코틀린 코루틴을 도입한다고 해서 기존 코드를 크게 수정할 필요 없다.

초보 개발자들이 사용하는 데도 무리가 없다.

 

이러한 이유로 코틀린 코루틴을 배워야한다.

 

코루틴 사용

스레드 전환

- 안드로이드에서의 문제: 하나의 앱에서 뷰를 다루는 스레드가 하나만 존재하고, 이 스레드는 가장 중요한 스레드라 블로킹 되면 안된다.

- 스레드 전환을 통해 위 문제를 해결할 수 있다.

- 블로킹이 가능한 스레드를 먼저 사용하고, 이후 메인 스레드로 전환한다.

 

// 과거 방식

fun onCreate() {
	thread {
    	val news = getNewsFromApi()
        val sortedNews = news
        	.sortedByDescending { it.pubilshedAt }
        runOnUiThread {
        	view.showNews(sortedNews)
        }
    }
}

 

[문제]

- 스레드 실행 시 멈출 수 없어 메모리 누수 발생 가능성 있음

- 스레드 생성에 대한 비용 이슈

- 잦은 스레드 전환으로 인한 복잡도 및 관리 어려움

 

 

콜백

- 코루틴 사용이 필요한 또 다른 이유

 

[문제]

- 중간에 작업 취소가 어려움

- 가독성이 낮음

- 작업 순서 관리가 어려움

 

 

RxJava와 리액티브 스트림

- 리액티브 스트림은 스레드 전환과 동시성 처리를 지원. 따라서 애플리케이션 내의 연산에 대한 병렬 처리 가능

 

- RxJava 사용 방법이 콜백 보다 좋은 점

   - 메모리 누수 없음, 취소 가능, 적절한 스레드 사용

- 단점: 구현이 복잡(zip, flatMap 등), 러닝 커브

 

 

코틀린 코루틴 사용

- 핵심 기능: 코루틴을 특정 지점에서 멈추고 이후에 재개 가능

- 예시: 메인 스레드에서 실행하고 API에서 데이터 가져올 때 잠시 중단 처리

 

// 코틀린 코루틴 사용

fun onCreate() {
	viewModelScope.launch {
    	val news = getNewsFromApi()
        val sortedNews = news
        	.sortedByDescending { it.publishedAt }
        view.showNews(sortedNews)
    }
}

 

- 메인 스레드에서 코드 실행, but 스레드 블로킹 없음

- 데이터가 오는걸 기다릴 때 코루틴을 중단하는 방식으로 작동 (메인 스레드에서 다른 액션 처리 가능)

 

[예시]

- 세 개의 엔드포인트를 호출해야 하는 문제에 대한 해결

fun showNews() {
	viewModelScope.launch {
    	val config = getConfigFromApi()
        val news = getNewsFromApi()
        val user = getUserFromApi()
        view.showNews(user, news)
    }
}

// 위 방식을 코루틴 라이브러리를 사용해서 아래와 같이 개선

fun showNews() {
	viewModelScope.launch {
    	val config = async { getConfigFromApi() }
        val news = async { getNewsFromApi() }
        val user = async { getUserFromApi()}
        view.showNews(user.await(), news.await())
    }
}

 

 

백엔드에서의 코루틴 사용

- 스레드를 코루틴으로 바꾸는 대부분의 환경에서는 suspend 만 추가하는 것으로 충분

- 코루틴 도입 시 동시성 쉽게 구현 및 테스트 가능

 

코루틴을 사용 하는 가장 중요한 이유: 스레드에 대한 비용

 

- 스레드는 명시적으로 생성 및 유지되어야 하며, 메모리도 할당되어야한다.
  대규모 서비스에서 응답을 기다릴 때마다 블로킹한다면, 메모리 및 프로세서 사용에 대한 비용 이슈가 생길 것이다.

 

[예시]

- 첫번째: 10만 개의 스레드 만들고 1초 동안 슬립

- 두번째: 코루틴 사용하여 스레드 대신 코루틴 중단. 1초 기다린 후 모든 점을 출력

fun main() {
	repeat(100_000)
    	thread {
        	Thread.sleep(1000L)
            print(".")
        }
    }
}


// 코루틴 사용
fun main() {
	repeat(100_000)
    	launch {
        	delay(1000L)
            print(".")
        }
    }
}

 

 

 

본 챕터는 코틀린 코루틴을 배워야하는 이유에 대한 가볍지만 핵심을 포함한 챕터였다.