ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CoroutineContext의 이해
    code 2025. 3. 11. 23:05
    반응형
    SMALL

    1. CoroutineContext란?

    **CoroutineContext**는 코루틴의 실행 환경을 정의하는 컨텍스트 정보를 담고 있는 Key-Value 형식의 데이터 구조입니다.
    코루틴을 실행할 때 디스패처(Dispatcher), Job, 예외 핸들러 등의 속성을 설정할 수 있도록 도와줍니다.

    💡 한 마디로?

    코루틴의 실행 방식과 환경을 정의하는 역할


    2. CoroutineContext의 구성 요소

    CoroutineContext는 여러 요소들의 조합으로 이루어지며, 각 요소는 특정 역할을 담당합니다.

    요소설명

    Dispatcher 코루틴이 실행될 스레드를 결정 (예: Dispatchers.IO, Dispatchers.Main)
    Job 코루틴의 실행 단위를 나타내며, 취소나 부모-자식 관계를 관리
    CoroutineName 코루틴의 이름을 설정하여 디버깅을 쉽게 함
    CoroutineExceptionHandler 예외 발생 시 처리할 핸들러 지정

    각 요소는 CoroutineContext의 일부로 결합되며, 하나의 CoroutineContext는 여러 요소를 포함할 수 있습니다.


    3. CoroutineContext의 원리

    • CoroutineContext는 불변 객체
      • plus(+) 연산을 통해 새로운 CoroutineContext를 만들 수 있음 (기존 값을 수정하는 것이 아니라 새로운 컨텍스트를 생성)
    • 코루틴의 실행 환경을 설정하는 데 사용
      • 어떤 스레드에서 실행할지, 어떤 Job이 포함되는지 등의 실행 규칙을 설정 가능
    • 필요한 컨텍스트만 덮어쓸 수 있음
      • 기존의 컨텍스트에서 일부 요소만 변경하여 새로운 컨텍스트 생성 가능

    4. CoroutineContext 사용법 및 예제

    (1) 기본적인 CoroutineContext 활용

    import kotlinx.coroutines.*
    
    fun main() = runBlocking {
        val context = Dispatchers.Default + CoroutineName("MyCoroutine")
        
        launch(context) {
            println("코루틴 실행 중... (스레드: ${Thread.currentThread().name})")
        }
    }
    
    코루틴 실행 중... (스레드: DefaultDispatcher-worker-1)

    설명

    • Dispatchers.Default를 사용하여 백그라운드 스레드에서 실행
    • CoroutineName("MyCoroutine")을 추가하여 디버깅 시 이름을 확인 가능

    (2) CoroutineContext 요소를 개별적으로 다루기

    import kotlinx.coroutines.*
    
    fun main() = runBlocking {
        val job = Job()
        val dispatcher = Dispatchers.IO
        val coroutineName = CoroutineName("CustomCoroutine")
    
        val context = job + dispatcher + coroutineName
    
        launch(context) {
            println("Coroutine 실행! (스레드: ${Thread.currentThread().name})")
        }
    }

    설명

    • Job()을 추가하여 코루틴을 개별적으로 취소할 수 있도록 설정
    • Dispatchers.IO를 사용하여 입출력(IO) 작업을 위한 스레드에서 실행

    (3) CoroutineExceptionHandler를 추가하여 예외 처리

     
    import kotlinx.coroutines.*
    
    fun main() = runBlocking {
        val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
            println("예외 발생: ${throwable.message}")
        }
    
        val context = Dispatchers.Default + exceptionHandler
    
        launch(context) {
            throw RuntimeException("에러 발생!")
        }
    }
    
    예외 발생: 에러 발생!

    설명

    • CoroutineExceptionHandler를 사용하여 코루틴 내에서 발생한 예외를 처리
    • 예외가 발생해도 앱이 강제 종료되지 않고 정상적으로 예외를 로그로 출력

    (4) 코루틴 내부에서 Context 변경하기

    import kotlinx.coroutines.*
    
    fun main() = runBlocking {
        val context = Dispatchers.IO + CoroutineName("InitialContext")
    
        launch(context) {
            println("초기 컨텍스트: ${coroutineContext}")
    
            withContext(Dispatchers.Default + CoroutineName("ChangedContext")) {
                println("변경된 컨텍스트: ${coroutineContext}")
            }
        }
    }
    
    초기 컨텍스트: [CoroutineName(InitialContext), Dispatchers.IO]
    변경된 컨텍스트: [CoroutineName(ChangedContext), Dispatchers.Default]

    설명

    • withContext를 사용하면 코루틴 내부에서 특정 블록만 다른 컨텍스트에서 실행 가능
    • Dispatchers.IO → Dispatchers.Default로 변경되었음을 확인 가능

    5. CoroutineContext를 활용한 베스트 프랙티스

    🔹 컨텍스트를 조합하여 원하는 실행 환경을 구성하자

    • Dispatchers.IO + CoroutineExceptionHandler + Job 등을 조합하여 효율적인 코루틴 실행 환경 설정

    🔹 예외 처리는 반드시 CoroutineExceptionHandler를 활용

    • 예외가 발생해도 앱이 정상적으로 동작하도록 핸들링 필수

    🔹 withContext를 활용하여 필요한 경우에만 컨텍스트 변경

    • 전체 코루틴이 아닌 특정 블록만 다른 컨텍스트에서 실행할 때 사용

    🔹 코루틴의 Job을 활용하여 명확한 취소 관리

    • val job = Job()을 사용하여 부모-자식 관계를 유지하고 적절히 취소

    6. 정리

    CoroutineContext란?

    • 코루틴의 실행 환경을 정의하는 Key-Value 형식의 데이터 구조

    CoroutineContext의 주요 요소

    • Dispatcher (스레드 결정), Job (코루틴 관리), CoroutineExceptionHandler (예외 처리), CoroutineName (디버깅 용도)

    핵심 개념

    • 불변 객체이며, + 연산으로 새로운 컨텍스트를 만들 수 있음
    • withContext를 사용하여 특정 블록에서만 컨텍스트 변경 가능
    • CoroutineExceptionHandler로 예외를 안전하게 처리

    LIST

    'code' 카테고리의 다른 글

    [와인] 19 크라임스 쉬라즈  (3) 2025.03.17
    CoroutineScope - launch  (1) 2025.03.13
    Kotlin의 async & await 이해하기  (0) 2025.03.10
    [Kotlin] apply, run, with, let, also  (0) 2025.03.10
    @Qualifier 이란??  (0) 2025.03.09
Designed by Tistory.