본문 바로가기

카테고리 없음

[Kotlin] 코루틴 완전 정리: Scope · Builder · Dispatcher · suspend 함수 한눈에 이해하기

반응형

코틀린 사용 구조

[1].[2]([3]) {
    [4]
}

 

[1] 생명주기 범위 (CoroutineScope) 코루틴이 살아있는 범위를 지정 (Optional)
[2] 코루틴 실행 함수 launch, async, withContext 등 실행 방식 결정
[3] Dispatcher 어떤 스레드(큐)에서 실행할지
[4] suspend 함수 실행 실제 일시중단 작업 수행

[1] 생명주기 범위 (CoroutineScope)

다른 scope는 내부적으로 CoroutineScope + Dispatcher를 포함하고 있기 때문에, 다시 ()로 Dispatcher를 지정해줄 필요가 없음

값 설명 사용 위치 종료 시점

(생략 불가) scope 생략 시 컴파일 에러 발생 반드시 명시 필요  
CoroutineScope(...) 직접 생성한 사용자 지정 scope 일반 클래스 등 직접 cancel해야함
viewModelScope ViewModel의 생명주기와 연결 ViewModel 내부 viewModel 끝날때
lifecycleScope LifecycleOwner (Activity/Fragment)의 생명주기와 연결 UI 컴포넌트 LifecycleOwner에 따라서
GlobalScope 앱 전체에서 살아있는 범위 (자동 취소 없음) ❗ 사용 지양 앱이 죽을때 까지 실행

[2] 코루틴 실행 함수 (빌더)

함수 반환 타입 설명 사용 목적

launch Job 결과 없이 실행 UI 업데이트, 단순 실행
async Deferred<T> 결과를 비동기로 반환 계산, 네트워크 등 결과 필요할 때
withContext T 컨텍스트 변경 후 결과 반환 /Dispatcher 변경용 스레드 변경하며 suspend 함수 실행
runBlocking T 코루틴을 블로킹(동기) 방식으로 실행 / 실무 X main() 함수, 테스트용
// launch, async 사용법
CoroutineScope(Dispatchers.Main).launch {

// runBlocking = 코루틴 "시작점"에서 전체 묶기 (블로킹)
fun main() = runBlocking {
    // 코루틴 실행
}

// withContext = "코루틴 내부"에서 Dispatcher 바꾸기 (비블로킹)
viewModelScope.launch {
    val result = withContext(Dispatchers.IO) {
        longTask()
    }
}

항목 withContext async-await

용도 컨텍스트(Dispatcher) 전환 + 결과 처리 병렬 비동기 실행 + 결과 처리
실행 시점 즉시 실행 지연 실행 (lazy)
병렬 처리 ❌ 불가 (순차 실행) ✅ 가능 (여러 개 동시에 실행 가능)
반환값 T (그냥 값) Deferred<T> → await() 해야 결과 받음
코드 목적 스레드 전환하면서 작업 하나만 할 때 여러 비동기 작업을 동시에 처리할 때
✅ withContext – 순차 실행
val data = withContext(Dispatchers.IO) {
    fetchFromNetwork()
}
val result = withContext(Dispatchers.Default) {
    processData(data)
}

✅ async-await – 병렬 실행
val networkDeferred = async(Dispatchers.IO) { fetchFromNetwork() }
val fileDeferred = async(Dispatchers.IO) { readFromFile() }

val result = combine(networkDeferred.await(), fileDeferred.await())

[3] Dispatcher 종류 (실행 스레드)

Dispatcher 스레드 종류 설명

생략 가능 Scope에 설정된 Dispatcher를 따라감 예: viewModelScope는 기본 Main
Dispatchers.Main 메인(UI) 스레드 UI 업데이트, LiveData 변경 등
Dispatchers.IO 백그라운드 I/O 스레드 파일, DB, 네트워크 작업
Dispatchers.Default 백그라운드 CPU 스레드 무거운 연산, 데이터 처리
Dispatchers.Unconfined 제한 없음 (컨텍스트에 따라 다름) 테스트, 특수 용도에만 사용

[4] 일시중단 함수 (suspend함수)

함수 예시 설명

delay(timeMillis) 지정 시간 동안 중단 (스레드 점유 X)
repository.fetchData() 네트워크 요청 등 실제 suspend 작업
withContext(Dispatcher) suspend 함수 내부에서 컨텍스트 전환
apiService.getUser() Retrofit에서 suspend로 정의된 API 호출

예시 코드

viewModelScope.launch(Dispatchers.Main) {
    val data = withContext(Dispatchers.IO) {
        repository.fetchData()
    }
    _state.value = data
}

위치 값 설명

[1] viewModelScope ViewModel의 생명주기와 연결
[2] launch 결과 없이 코루틴 실행
[3] Dispatchers.Main UI 스레드에서 시작
[4] withContext(Dispatchers.IO) { repository.fetchData() } I/O 스레드에서 suspend 함수 실행
반응형