개발일지

Kotlin in A..Z - Coroutine(5) CoroutineScope 본문

Kotlin (코틀린)

Kotlin in A..Z - Coroutine(5) CoroutineScope

강태종 2020. 10. 27. 22:19

Coroutine에 접근하기 위해서는 CoroutineScope를 사용해서 접근해야 한다.

CoroutineScope는 interface형식으로 정의되어 있고, CoroutineContext를 사용해서 생성하거나, 미리 정의된 GlobalScope를 사용할 수 있다.


GlobalScope

GlobalScope는 별도의 생명주기가 없고, 실행되면 작업이 종료되거나 앱이 종료될 때까지 남아있는다.

fun main() = runBlocking {
    GlobalScope.launch {
        println("Running on GlobalScope ${Thread.currentThread().name}")
    }

    delay(1000L)
}
Running on GlobalScope DefaultDispatcher-worker-1

CoroutineScope

CoroutineScope는 Dispatchers에 미리 정의된 CoroutineContext를 사용하여 코루틴의 실행 쓰레드와 생명주기를 조절할 수 있고, 상속하여 더욱 자세하게 작동시킬 수 있다.

fun main(): Unit = runBlocking {
    CoroutineScope(Dispatchers.IO).launch {
        println("Running on CoroutineScope(Main) ${Thread.currentThread().name}")
    }
}
Running on CoroutineScope(Main) DefaultDispatcher-worker-1

좋지않은 코루틴 구조

중간에 Exception이 발생했지만 GlobalScope는 종료되지 않고 계속 실행된다.

GlobalScope의 Job을 핸들링하기 어렵다.

fun main(): Unit = runBlocking {
    try {
        doSomething()
        
        delay(2000L)
        throw Exception()
    } catch (e: Exception) {
        println("Error")
    }

    // 결과를 확인하기 위한 delay
    delay(10000L)
}

fun doSomething() = GlobalScope.launch {
    repeat(5) {
        delay(1000L)
        println("Running $it")
    }
}
Running 0
Error
Running 1
Running 2
Running 3
Running 4

 

async를 활용하였을 때 async도 CoroutineBuilder이고 새로운 Job에서 실행되기 때문에 Exception이 발생해도 계속 실행된다.

fun main(): Unit = runBlocking {
    try {
        async { doSomething() }

        delay(2000L)
        throw Exception()
    } catch (e: Exception) {
        println("Exception")
    }

    // 결과를 확인하기 위한 delay
    delay(10000L)
}

suspend fun doSomething() {
    repeat(5) {
        delay(1000L)
        println("Running $it")
    }
}
Running 0
Exception
Running 1
Running 2
Running 3
Running 4

Process finished with exit code 0

권장하는 코루틴 구조

새로운 CoroutineScope에서 작업을 진행하다 예외가 발생할 경우 해당 Scope에 모든 Coroutine이 중단되면서 예외를 던진다.

fun main(): Unit = runBlocking {
    try {
        doSomething()
    } catch (e: Exception) {
        println("Exception")
    }

    // 결과를 확인하기 위한 delay
    delay(10000L)
}

suspend fun doSomething() = coroutineScope {
    async {
        repeat(5) {
            delay(1000L)
            println("Running $it")
        }
    }

    delay(3000L)
    throw Exception()
    Unit
}
Running 0
Running 1
Exception

'Kotlin (코틀린)' 카테고리의 다른 글

Kotlin in A..Z - Aggregate Operation  (0) 2020.11.28
Kotlin in A..Z - Collection  (0) 2020.11.27
Kotlin in A..Z - Coroutine(4) async  (0) 2020.10.27
Kotlin in A..Z - Coroutine(3) Cancel  (0) 2020.10.15
Kotlin in A..Z - Coroutine(2) 기본  (0) 2020.10.15
Comments