1. 코루틴 컨텍스트란?
- 코루틴 컨텍스트(CoroutineContext)는 코틀린 코루틴의 실행 환경을 정의하는 인터페이스입니다.
- 코루틴이 어떤 스레드에서 실행될지, 어떤 예외 처리기를 사용할지, 코루틴의 생명주기를 어떻게 관리할지 등의 정보를 포함합니다.
- 코루틴 컨텍스트는 여러 요소(Element)의 집합으로, 각 요소는 특정 측면(스레드 정책, 예외 처리 등)을 담당합니다.
CoroutineContext는 일종의 맵(Map)과 유사한 인덱싱된 집합으로, 키(Key)와 값(Element)의 쌍으로 구성됩니다.
정보
코루틴 컨텍스트는 코루틴이 실행되는 환경과 정책을 결정합니다. 자바의 ExecutorService나 스레드 관련 설정보다 더 풍부한 정보를 담고 있어 코루틴의 강력한 기능을 가능하게 합니다.
2. 코루틴 컨텍스트의 주요 구성 요소
2.1 CoroutineDispatcher (디스패처)
- 코루틴이 어떤 스레드 또는 스레드 풀에서 실행될지 결정합니다.
- 코루틴의 실행 컨텍스트를 제공하는 가장 기본적인 요소입니다.
- Dispatchers 참고
2.2 Job
- 코루틴의 생명주기를 관리하는 요소입니다.
- 코루틴의 상태를 추적하고, 코루틴을 취소하거나 완료를 대기할 수 있습니다.
- 부모-자식 관계를 통해 구조화된 동시성(structured concurrency)을 지원합니다.
2.2.1 Job 생성 및 사용
// 코루틴 빌더로 Job 생성
val job = launch {
// 작업 수행
}
// 명시적 Job 생성
val job = Job()
launch(job) {
// job에 연결된 코루틴
}
// Job 상태 확인
println("Job is active: ${job.isActive}")
println("Job is completed: ${job.isCompleted}")
println("Job is cancelled: ${job.isCancelled}")
// Job 완료 대기
job.join() // 코루틴 내부에서 호출
// Job 취소
job.cancel("취소 이유")
2.2.2 Job의 상태
- Job은 다음과 같은 상태를 가집니다:
New: 아직 실행되지 않은 상태Active: 실행 중인 상태Completing: 작업이 완료되고 있는 상태Completed: 정상적으로 완료된 상태Cancelling: 취소 중인 상태Cancelled: 취소된 상태
2.2.3 부모-자식 관계
val parentJob = launch {
// 부모 코루틴
val childJob = launch {
// 자식 코루틴
}
// 부모가 취소되면 자식도 자동으로 취소됩니다
}
// 부모를 취소하면 모든 자식도 취소됩니다
parentJob.cancel()
- 코루틴은 부모-자식 관계를 통해 구조화된 동시성을 지원합니다.
- 부모 코루틴이 취소되면 모든 자식 코루틴도 자동으로 취소됩니다.
- 자식 코루틴이 예외로 실패하면 부모 코루틴도 취소됩니다.
2.3 CoroutineName
- 디버깅을 위해 코루틴에 이름을 부여하는 요소입니다.
- 로그에서 특정 코루틴을 식별하는 데 유용합니다.
launch(CoroutineName("데이터로딩코루틴")) {
println("코루틴 이름: ${coroutineContext[CoroutineName]?.name}")
// 출력: 코루틴 이름: 데이터로딩코루틴
}
2.4 CoroutineExceptionHandler
- 코루틴 내에서 발생한 예외를 처리하는 요소입니다.
- 특히 루트 코루틴의 예외를 처리할 때 중요합니다.
val exceptionHandler = CoroutineExceptionHandler { context, exception ->
println("코루틴 예외 발생: $exception")
println("코루틴 컨텍스트: $context")
}
// 예외 핸들러 사용
launch(exceptionHandler) {
throw RuntimeException("에러 발생!")
}
경고
CoroutineExceptionHandler는 루트 코루틴(다른 코루틴의 자식이 아닌 코루틴)에서만 동작합니다. 자식 코루틴의 예외는 부모로 전파되므로, 부모 코루틴에 예외 핸들러를 설정해야 합니다.
3. 코루틴 컨텍스트 결합과 상속
3.1 컨텍스트 요소 결합
// 여러 컨텍스트 요소 결합
val combinedContext = Dispatchers.IO + CoroutineName("네트워크 작업") + exceptionHandler
launch(combinedContext) {
// 결합된 컨텍스트에서 실행
}