Gemstone's Devlog

[Coroutine] Async 본문

Kotlin (Android)

[Coroutine] Async

Gemstone 2022. 6. 23. 20:04

Async 게으르게 사용하기

async 키워드를 사용하는 순간 코드 블록이 수행을 준비하는데, 

async(start = CoroutineStart.LAZY)로 인자를 전달하면 우리가 원하는 순간 수행을 준비하게 할 수 있습니다.

이후 start 메서드를 이용해 수행을 준비하게 할 수 있습니다.

 

import kotlin.random.Random
import kotlin.system.*
import kotlinx.coroutines.*

suspend fun getRandom1(): Int {
    delay(1000L)
    return Random.nextInt(0, 500)
}

suspend fun getRandom2(): Int {
    delay(1000L)
    return Random.nextInt(0, 500)
}

fun main() = runBlocking {
    val elapsedTime = measureTimeMillis {
        val value1 = async(start = CoroutineStart.LAZY) { getRandom1() }
        val value2 = async(start = CoroutineStart.LAZY) { getRandom2() }

        value1.start()
        value2.start()

        println("${value1.await()} + ${value2.await()} = ${value1.await() + value2.await()}")
    }
    println(elapsedTime)
}

실행 결과

 

이렇게 하면 코루틴이 만들어지기는 하지만 수행이 예약이 되지 않는다!

수행 예약을 하기 위해 start()함수를 붙여주어야 하는데

이렇게 해주어야만 async 블록들이 수행 예약되어 큐에 올라가게 된다.

 

 

Async를 사용한 구조적인 동시성

코드를 수행하다 보면 예외가 발생할 수 있습니다.

예외가 발생하면 위쪽의 코루틴 스코프와 아래쪽의 코루틴 스코프가 취소됩니다.

import kotlin.random.Random
import kotlin.system.*
import kotlinx.coroutines.*

suspend fun getRandom1(): Int {
    try {
        delay(1000L)
        return Random.nextInt(0, 500)
    } finally {
        println("getRandom1 is cancelled.")
    }
}

suspend fun getRandom2(): Int {
    delay(500L)
    throw IllegalStateException()
}

suspend fun doSomething() = coroutineScope { // 부모 코루틴 // 캔슬해라.
    val value1 = async { getRandom1() } // 자식 코루틴 // 문제가 발생했으니깐 캔슬해라.
    val value2 = async { getRandom2() } // 자식 코루틴 // 문제 발생
    try { 
        println("${value1.await()} + ${value2.await()} = ${value1.await() + value2.await()}")
    } finally {
        println("doSomething is cancelled.")
    }
}

fun main() = runBlocking {
    try {
        doSomething()
    } catch (e: IllegalStateException) {
        println("doSomething failed: $e")
    }
}

출력 결과

getRandom2가 오류가 나서 getRandom1 doSomething은 취소됩니다. (JobCancellationException 발생)

문제가 된 IllegalStateException도 외부에서 잡아줘야 합니다.

 

요약 : 어떤 형제가 문제가 생기면 다른 형제들도 문제가 생기고 부모까지 문제가 생긴다!

'Kotlin (Android)' 카테고리의 다른 글

Room 지속성 라이브러리 공부!  (0) 2022.06.28
[Coroutine Flow] 콜백 기반 api -> flow 변경 방법  (0) 2022.06.24
Jetpack Navigation 공부  (0) 2022.06.17
GSON 대신 Moshi?  (0) 2022.06.15
Paging 3.0 라이브러리 정리  (0) 2022.06.14