[Coroutine] launch와 async에 대해

 

Dispatcher에 Coroutine을 붙이는 작업을 하기 위해서는 async와 launch 두 가지 메소드를 이용할 수 있습니다.

그렇다면 launch와 async에 차이점과 언제 사용해야하는지 알아보려고 합니다!


launch란

launch를 통해 코루틴 블록을 만드는 것을 코루틴 빌더 생성이라고 하며,

launch는 현재 스레드를 차단하지 않고 새로운 코루틴을 실행할 수 있으며 특정 결과값 없이 Job 객체를 반환합니다.

fun main() {
    val job = GlobalScope.launch {
        delay(1000L)
        println("coroutine launch")
    }

    println("call in main")
    println("job is Active: ${job.isActive}, Completed: ${job.isCompleted}")
    Thread.sleep(3000L)
    println("job is Active: ${job.isActive}, Completed: ${job.isCompleted}")
}

위 코드를 실행하면, 아래와 같은 결과를 얻게 됩니다.

call in main
job is Active: true, Completed: false
coroutine launch
job is Active: false, Completed: true

main 함수는 메인 스레드에서 실행이 되며 launch 내부의 코드는 코루틴 코드로 메인 스레드와는 별도로 실행 되어 넌블록킹 코드입니다.

"call in main"이 먼저 출력된 후 "job.isActive: true, Completed: false"이 출력되고, 1초 뒤 launch, 3초 뒤 "job.isActive: false, Completed: true "가 실행됩니다.

 

이처럼 launch를 통해 코루틴 블록을 만드는 것을 코루틴 빌더의 생성 이라고 하며 launch는 현재 스레드를 차단하지 않고 새로운 코루틴을 생성하며, 특정 결과는 없고 Job 객체를 반환하기 때문에, value값을 받는 동작이 아닐 경우 lauch를 사용하면 됩니다.

 


 

async란

launch와 마찬가지로 Dispatcher에 Coroutine을 붙이는 작업을 하는 메소드이며 코루틴 빌더를 생성한다. 하지만, launch와 다르게 async는 결과를 반환하며 결과값은 Deferred로 감싸서 반환합니다.

** 이는 취소 불가능한 Non-Blocking Cancellable Future를 의미

 

fun main() {
    CoroutineScope(Dispatchers.Main).launch {
        val deferredInt : Deferred<Int> = async {
            1
        }
        val value = deferredInt.await()
        println(value)
    }
}

해당 코드는 deferredInt에 넣어진 1 값이 출력됩니다.

 

여기서 사용되는 await()은 해당 코루틴의 작업이 끝나는 시점을 기다렸다 결과를 받아오는 역할을 하며,  스레드를 방해하지 않고 Deferred 값이 계산될 때 까지 기다리게 하는 함수입니다. 이처럼 Deferred<T>는 결과가 반환되기 까지 기다리며, 이를 우리는 일시정지 상태라고 말할 수 있습니다. 그렇기 때문에, await() 메소드는 코루틴 내부에서만 사용이 가능하고, 바깥쪽에 코드를 작성한 경우 오류가 발생합니다.

 


launch와 async 차이점 정리

  결과 반환 반환 타입 
launch X Job
asycn O Deferred

 

 

참고하다 잘 정리된 부분이 있어 사진도 함께 가져왔습니다:)

 

🌈 마무리

launch와 async가 각각 어떻게 사용되는지 알아보는 시간을 가졌는데요, 평소에 정확하기 알지 못하고 사용한 제 자신을 반성하게 되었습니다. 이번 계기로 코루틴에 대해 조금 더 깊이 있고 정확하게 공부하는 시간을 가져보려고 합니다!