BackEnd/coroutine

Coroutine 순차 처리

hanseom 2025. 5. 9. 23:50
반응형

  '토큰 업데이트 후 네트워크 요청', '이미지 변환 후 업로드 요청' 같이 작업 간에 선후 관계(종속성) 있는 작업들이 존재합니다.

 

  다음은 순차처리 되지 않는 코드입니다. 토큰이 업데이트 되고 네트워크 요청을 해야하나, 병렬로 처리되어 토큰 업데이트 완료 전 네트워크 요청이 일어납니다.

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> {
    val updateTokenJob = launch(Dispatchers.IO) {
        println("[${Thread.currentThread().name}] 토큰 업데이트 시작")
        delay(100L) // 새로운 토큰을 가져오는데 걸리는 시간
        println("[${Thread.currentThread().name}] 토큰 업데이트 완료")
    }

    val networkCallJob = launch(Dispatchers.IO) {
        println("[${Thread.currentThread().name}] 네트워크 요청")
    }
}

 

Job 객체

  • 코루틴의 실행과 생명주기를 관리하는 핵심 인터페이스입니다.
  • launch, async 같은 코루틴 빌더 함수는 코루틴을 생성할 때 Job 객체를 반환합니다.
  • Job 객체를 통해 코루틴의 상태를 추적하고 제어할 수 있습니다.

 

join 함수

  Job 객체의 join 함수를 사용하면, 코루틴 순차 처리가 가능합니다. join 함수를 사용하면 join 함수의 대상이 된 코루틴이 완료될 때까지 join 함수를 호출한 코루틴이 일시 중단됩니다. 아래 코드에서는 runBlocking 코루틴이 updateTokenJob이 완료될 때까지 일시 중단됩니다.

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> {
    val updateTokenJob = launch(Dispatchers.IO) {
        println("[${Thread.currentThread().name}] 토큰 업데이트 시작")
        delay(100L)
        println("[${Thread.currentThread().name}] 토큰 업데이트 완료")
    }
    updateTokenJob.join() // networkCallJob 실행 전 updateTokenJob.join() 호출

    val networkCallJob = launch(Dispatchers.IO) {
        println("[${Thread.currentThread().name}] 네트워크 요청")
    }
}

 

joinAll 함수

  joinAll 함수를 사용하면 복수의 코루틴 순차 처리가 가능합니다. 실무에서는 서로 독립적인 복수의 코루틴을 병렬 실행한 후 이들이 모두 완료되었을 때 다음 작업을 실행해야 하는 경우가 많습니다.

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> {
    val convertImageJob1: Job = launch(Dispatchers.Default) {
        Thread.sleep(1000L) // 이미지1 변환 작업 실행
        println("[${Thread.currentThread().name}] 이미지1 변환 완료")
    }
    val convertImageJob2: Job = launch(Dispatchers.Default) {
        Thread.sleep(1000L) // 이미지2 변환 작업 실행
        println("[${Thread.currentThread().name}] 이미지2 변환 완료")
    }

    joinAll(convertImageJob1, convertImageJob2) // 이미지 1,2가 모두 변환될 때까지 대기

    listOf(convertImageJob1, convertImageJob2).joinAll()

    val uploadImageJob: Job = launch(Dispatchers.IO) {
        println("[${Thread.currentThread().name}] 이미지1,2 업로드")
    }
}
반응형