1. 코루틴 디스패처란?
- 코루틴 디스패처(Dispatcher)는 코루틴이 실행될 스레드 또는 스레드 풀을 결정하는 중요한 요소입니다.
- 디스패처는 코루틴의 실행 컨텍스트(CoroutineContext)의 핵심 구성 요소로, 코루틴이 어떤 스레드에서 실행될지를 제어합니다.
- 적절한 디스패처 선택은 애플리케이션의 응답성과 성능에 직접적인 영향을 미칩니다.
- launch와 async 같은 모든 코루틴 빌더들은 선택적으로 CoroutineContext 매개변수를 받을 수 있습니다.
- 이를 통해 새로운 코루틴을 위한 디스패처와 다른 컨텍스트 요소들을 명시적으로 지정할 수 있습니다.
1.1 디스패처의 역할
- 코루틴 코드 블록을 적절한 스레드에 배정(dispatch)합니다.
- 작업 특성에 맞는 스레드 풀을 관리합니다.
- 코루틴 간의 작업 전환과 스레드 전환을 효율적으로 처리합니다.
- 스레드 자원을 효과적으로 활용하여 시스템 성능을 최적화합니다.
정보
코루틴은 실행되는 스레드에 종속되지 않으며, 한 스레드에서 일시 중단되었다가 다른 스레드에서 재개될 수 있습니다. 이러한 유연성을 제공하는 것이 바로 디스패처의 역할입니다.
2. 코틀린에서 제공하는 표준 디스패처
코틀린의 kotlinx.coroutines
라이브러리는 다양한 사용 사례에 맞게 설계된 여러 표준 디스패처를 제공합니다.
2.1 Dispatchers.Default
- CPU 집약적인 작업을 위해 최적화된 디스패처입니다.
- JVM의 공유 스레드 풀을 사용합니다.
- 기본적으로 시스템 코어 수에 맞춰진 스레드 수(최소 2개)를 갖습니다.
- 명시적으로 디스패처를 지정하지 않으면 기본적으로 사용되는 디스패처입니다.
사용 예시
import kotlinx.coroutines.*
suspend fun performComplexCalculation() {
withContext(Dispatchers.Default) {
// CPU 집약적인 계산 작업
val result = (1..1_000_000).map { it * it }.sum()
println("계산 결과: $result")
}
}
이 예시에서는 많은 수의 제곱 계산과 합산 과정이 CPU 자원을 집중적으로 사용하므로 Default 디스패처를 사용합니다.
2.2 Dispatchers.IO
- 입출력 작업에 최적화된 디스패처입니다.
- 네트워크 요청, 파일 작업, 데이터베이스 연산과 같은 블로킹 I/O 작업에 적합합니다.
- Default 디스패처와 스레드 풀을 공유하지만, 더 많은 스레드를 사용하도록 구성되어 있습니다.
- 많은 스레드가 I/O 작업으로 블로킹되더라도 다른 작업이 계속 실행될 수 있도록 합니다.
사용 예시
import kotlinx.coroutines.*
import java.io.File
suspend fun readFileContent(path: String): String {
return withContext(Dispatchers.IO) {
File(path).readText()
}
}
suspend fun fetchNetworkData(url: String): String {
return withContext(Dispatchers.IO) {
// URL 연결 및 데이터 가져오기
URL(url).readText()
}
}
파일 읽기와 네트워크 요청은 모두 I/O 작업이므로 IO 디스패처를 사용합니다.
2.3 Dispatchers.Main
- UI 스레드에서 실행되는 디스패처입니다.
- 백엔드 애플리케이션에서는 거의 사용하지 않습니다만, 특정 프레임워크에서는 이와 유사한 "메인" 스레드 개념이 있을 수 있습니다.
- 안드로이드, JavaFX, Swing 등의 UI 프레임워크에서 주로 사용됩니다.
- UI 업데이트와 같은 가벼운 작업에 적합합니다.
- 특히 안드로이드에서는
kotlinx-coroutines-android
의존성을 추가해야 사용할 수 있습니다.
경고
Main 디스패처는 UI 스레드에서 실행되므로, 오래 걸리는 작업을 이 디스패처에서 실행하면 UI가 멈추거나 응답하지 않을 수 있습니다.