-
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 - CoroutineContext는 불변 객체