본문 바로가기
Kotlin&Java/Coroutine

[Kotlin] Coroutine vs Thread

by 굿햄 2023. 1. 18.

Kotlin Coroutine 이해하기 2부

Kotlin Coroutine 개념 기초

Coroutine(코루틴)을 수도없이 사용해왔지만 이게 무슨뜻일지 궁금했다

Co(협력) + Routine(작업)으로 협력형 멀티태스킹이라 말할 수 있다고 한다. (이에 대한 자세한 내용은 하단에 링크 첨부)

 

Android Developer 사이트에서는 아래와 같이 정의하고 있다.

코루틴은 비동기적으로 실행되는 코드를 간소화하기 위해 Android에서 사용할 수 있는 동시 실행 설계 패턴입니다. 코루틴은 Kotlin 버전 1.3에 추가되었으며 다른 언어에서 확립된 개념을 기반으로 합니다.
Android에서 코루틴은 기본 스레드를 차단하여 앱이 응답하지 않게 만들 수도 있는 장기 실행 작업을 관리하는 데 도움이 됩니다. 코루틴을 사용하는 전문 개발자 중 50% 이상이 생산성이 향상되었다고 보고했습니다.

Android와 Kotlin Document의 설명을 보면 다른 언어와 다르게 async나 await가 Kotlin의 표준 라이브러리가 아니며, Suspend(일시중단) 기능의 개념은 안전성을 제공하고 Futures, Promise 보다 에러 발생률이 낮은 추상화를 제공한다.

 

즉, 기존에 사용하던 RxJava와 같이 비동기 처리를 위한 라이브러리이다.

 

그러나 주목해야 하는 주요 이유는 아래 4가지와 같다.

  • 경량: 코루틴을 실행 중인 스레드를 차단하지 않는 정지를 지원하므로 단일 스레드에서 많은 코루틴을 실행할 수 있습니다. 정지는 많은 동시 작업을 지원하면서도 차단보다 메모리를 절약합니다.
  • 메모리 누수 감소: 구조화된 동시 실행을 사용하여 범위 내에서 작업을 실행합니다.
  • 기본으로 제공되는 취소 지원: 실행 중인 코루틴 계층 구조를 통해 자동으로 취소가 전달됩니다.
  • Jetpack 통합: 많은 Jetpack 라이브러리에 코루틴을 완전히 지원하는 확장 프로그램이 포함되어 있습니다. 일부 라이브러리는 구조화된 동시 실행에 사용할 수 있는 자체 코루틴 범위도 제공합니다.

 

Coroutine 에서의 Thread 동작

놀라운 점은 Coroutine은 실행중인 스레드를 Block(차단)하는 대신 Suspend(정지)을 한다. 즉 단일 스레드에서 많은 코루틴을 실행하는 것이다.

 

이러한 이유는 Thread의 생성 Cost(비용)은 비싸며, 다른 Thread로 부터 결과를 전달받아야 할 때, Blocking이 발생하면 아무 작업없이 다른 작업이 끝날 때 까지 자원은 낭비된다.

낭비되는 Thread 예시

아래는 Block 코드 예제이다.

 

 

Coroutine의 Lightweight-Thread(경량 스레드)는 위와 같이 작업 단위가 Thread일 때 생기는 문제점을 개선할 수 있다.

 

경량 스레드의 동작

위의 이미지처럼 Coroutine1(또는 Job)의 작업이 일시 중단되면, 같은 스레드에서 Coroutine2의 작업을 수행하여 Blocking되는 상황을 회피할 수 있고 Thread를 재사용하여 생성 비용을 줄일 수 있다.

 

아래는 Suspend 코드의 예제이다. launch{ ... } 내의 동작이 일시정지 한 동안 다른 Job이 수행된다.

 

요약하면 아래와 같다.

코루틴은 스레드 안에서 수행되는 일시 중단 가능한 작업의 단위이다.
따라서 하나의 스레드에 여러 코루틴이 들어갈 수 있다.
Thread 스레드 Coroutine 코루틴
Task 단위: Thread
작업 단위로 Thread를 할당 & 해제
각 Thread는 Stack 메모리를 가지며, JVM Stack 영역 점유
Task 단위: Job(Coroutine)
작업 단위로 Coroutine 할당
Coroutine은 JVM Heap 영역에 쌓임

ⓒ 굿햄 2022. daryeou@gmail.com all rights reserved.

댓글