๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘/Kotlin

[Kotlin] Coroutines - Coroutine builder

interfacer_han 2024. 2. 12. 16:36

#1 Coroutine builder

 

kotlinx-coroutines-core

Core primitives to work with coroutines. Coroutine builder functions: Coroutine dispatchers implementing CoroutineDispatcher: More context elements: Synchronization primitives for coroutines: Top-level suspending functions: NameDescriptiondelayNon-blocking

kotlinlang.org

runBlocking์„ ์ œ์™ธํ•œ ์ฝ”๋ฃจํ‹ด ๋นŒ๋”๋Š” CoroutinesScope์˜ ํ™•์žฅ ํ•จ์ˆ˜(Extension functions)๋‹ค. CoroutineScope๊ฐ€ ์ฝ”๋ฃจํ‹ด ์ฝ”๋“œ ์˜์—ญ(Scope)๊ณผ ์•„๋‹Œ ์˜์—ญ์„ ๊ตฌ๋ถ„ํ•˜๋Š” ์—ญํ• ์ด๋ผ๋ฉด, Coroutine builder๋Š” ๊ทธ CoroutineScope ์˜์—ญ์˜ ์ฝ”๋ฃจํ‹ด ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ์—ญํ• ์ด๋‹ค. Coroutine builder๋Š” ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ๋ฅผ ์Šค๋ ˆ๋“œ ํ’€๋กœ๋ถ€ํ„ฐ ํ• ๋‹น๋ฐ›๋Š” ํ•จ์ˆ˜์ด๊ธฐ๋„ ํ•˜๋‹ค. Coroutine builder์˜ ์ข…๋ฅ˜๋Š” ์•„๋ž˜์˜ 4๊ฐ€์ง€๋‹ค.

#2 kotlinx.coroutines.runBlocking

 

[Kotlin] Coroutines - runBlocking

#1 ์ด์ „ ๊ธ€ [Kotlin] Coroutines - Coroutine builder #1 Coroutine builder kotlinx-coroutines-core Core primitives to work with coroutines. Coroutine builder functions: Coroutine dispatchers implementing CoroutineDispatcher: More context elements: Synchron

kenel.tistory.com

runBlocking์€ ์œ„ ๊ฒŒ์‹œ๊ธ€์—์„œ ๋‹ค๋ฃฌ๋‹ค.

 

#3 Coroutine builder - CoroutineScope.launch

#3-1 ์ฝ”๋“œ

import kotlinx.coroutines.*

fun performTaskInCoroutineScope(): Job {
    return CoroutineScope(Dispatchers.Default).launch {
        var x = 1
        repeat(5) {
            println(x++)
            delay(1000) // 1์ดˆ ๋Œ€๊ธฐ
        }
    }
}

fun main() {
    println("Start")

    val myJob = performTaskInCoroutineScope()

    println("Continuing...")

    runBlocking {
        // ํ•ด๋‹น Job์˜ ์™„๋ฃŒ๋ฅผ ๊ธฐ๋‹ค๋ฆผ
        myJob.join()
    }

    println("End")
}

/* ์ถœ๋ ฅ ๊ฒฐ๊ณผ
Start
Continuing...
1
2
3
4
5
End
*/

CoroutineScope.launch๋Š” ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋ฅผ Blocking(๋ธ”๋กœํ‚น)ํ•˜์ง€ ์•Š๊ณ , CoroutineContext์— ๋ช…์‹œ๋œ ์Šค๋ ˆ๋“œ์—์„œ ์ฝ”๋ฃจํ‹ด์„ ์‹คํ–‰ํ•œ๋‹ค. 'ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋ฅผ ๋ธ”๋กœํ‚นํ•œ๋‹ค'๋Š” ๊ฒƒ์€ 'ํ•ด๋‹น ์Šค๋ ˆ๋“œ์˜ ์ฝ”๋“œ ๋™์ž‘์„ ์ผ์‹œ ์ •์ง€ํ•จ'์„ ์˜๋ฏธํ•œ๋‹ค. ๋ธ”๋กœํ‚น์€ ํ˜„์žฌ ์Šค๋ ˆ๋“œ์™€ ์ฝ”๋ฃจํ‹ด์šฉ ์Šค๋ ˆ๋“œ์˜ ๋ณ‘๋ ฌ์  ๋™์‹œ ์‚ฌ์šฉ์ด๋ผ๋Š”, ์ฝ”๋ฃจํ‹ด์˜ ์ผ๋ฐ˜์ ์ธ ๋ชฉ์ ์— ๋ถ€ํ•ฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ด๋ฉฐ ๋Œ€ํ‘œ์ ์ธ ์ฝ”๋ฃจํ‹ด ํ•จ์ˆ˜์ธ launch๋Š” ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋ฅผ ๋ธ”๋กœํ‚นํ•˜์ง€ ์•Š์•„์•ผ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
 

#3-2 Job ์ธํ„ฐํŽ˜์ด์Šค

CoroutineScope.launch๋Š” ์ฝ”๋ฃจํ‹ด ์ฝ”๋“œ์˜ ๋ ˆํผ๋Ÿฐ์Šค ์—ญํ• ์„ ํ•˜๋Š” Job ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ฐ์ฒด๋ฅผ returnํ•œ๋‹ค. ์ด ๋ ˆํผ๋Ÿฐ์Šค ๊ฐ์ฒด๋ฅผ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•ด ํ•ด๋‹น ์ฝ”๋ฃจํ‹ด์„ ์ฐธ์กฐ(์ด ๋งํฌ์˜ #6-2)ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. CoroutineScope.launch๋Š” Job()๋งŒ์„ returnํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ํ•จ์ˆ˜์—์„œ๋Š”, ์ฝ”๋ฃจํ‹ด ์ฝ”๋“œ ์† ์–ด๋–ค ๊ณ„์‚ฐ์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ํ•  ์ˆ˜ ์—†๋‹ค.
 

#3-3 Job.join()

join์˜ ์‚ฌ์ „์  ์˜๋ฏธ๋Š” '์—ฐ๊ฒฐํ•˜๋‹ค, ํ•ฉ์ณ์ง€๋‹ค'๋‹ค. join()์„ ํ†ตํ•ด, ์–ธ์ œ ์™„๋ฃŒ๋  ์ง€ ๋ชจ๋ฅด๋Š” ์–ด๋–ค ์ฝ”๋ฃจํ‹ด์„ ์™„๋ฃŒ๋œ ์ƒํƒœ๋กœ ํ˜„์žฌ์™€ ์—ฐ๊ฒฐ์ง“๋Š”๋‹ค. ๋ง์ด ์–ด๋ ค์šด๋ฐ ๊ทธ๋ƒฅ Job์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ํ•จ์ˆ˜๋‹ค. ์œ„ ์ฝ”๋“œ์—์„œ join()์ด runBlocking { ... } ์•ˆ์— ๋“ค์–ด๊ฐ€ ์žˆ๋Š” ์ด์œ ๋Š” ์—ฌ๊ธฐ์— ์žˆ๋‹ค.
 

#4 Coroutine builder - CoroutineScope.async

#4-1 ์ฝ”๋“œ

import kotlinx.coroutines.*

fun calculateSumAsync(a: Int, b: Int): Deferred<Int> {
    return CoroutineScope(Dispatchers.Default).async {
        println("Calculating sum in background thread...")
        delay(1000) // 1์ดˆ ๋™์•ˆ ๋Œ€๊ธฐ (์‹ค์ œ๋กœ๋Š” ์–ด๋–ค ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋Œ€์ฒด๋  ์ˆ˜ ์žˆ์Œ)
        return@async a + b // ๊ณ„์‚ฐ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
    }
}

fun main() {
    println("Start")

    val deferredResult: Deferred<Int> = calculateSumAsync(5, 10) // Deferred ๊ฐ์ฒด ์ƒ์„ฑ

    println("Doing some other work...")

    // ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆผ
    // await() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•œ ํ›„ ์ž‘์—… ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์คŒ
    runBlocking {
        val result = deferredResult.await()
        println("Result: $result")
    }

    println("End")
}

/* ์ถœ๋ ฅ ๊ฒฐ๊ณผ
Start
Doing some other work...
Calculating sum in background thread...
Result: 15
End
*/

CoroutineScope.launch์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋ฅผ Blockingํ•˜์ง€ ์•Š๊ณ , CoroutineContext์— ๋ช…์‹œ๋œ ์Šค๋ ˆ๋“œ์—์„œ ์ฝ”๋ฃจํ‹ด์„ ์‹คํ–‰ํ•œ๋‹ค. ํ•˜์ง€๋งŒ, CoroutineScope.async์€ CoroutineScope.launch์™€ ๋‹ฌ๋ฆฌ Job()์ด ์•„๋‹Œ Deferred<T> ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ returnํ•œ๋‹ค.
 

#4-2 Deferred<T> ์ธํ„ฐํŽ˜์ด์Šค

Deferred<T> ์ธํ„ฐํŽ˜์ด์Šค๋Š” Job ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ž์‹์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋“  Deferred๋Š” Job์ด์ง€๋งŒ, ๋ชจ๋“  Job์ด Deferred์ธ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. Deferred๋Š” Job์„ ๋‹ค๋ค˜๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ผํ•˜๊ฒŒ ์ฐธ์กฐํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ Deferred๋Š” Job๊ณผ ๋‹ฌ๋ฆฌ, (๋ฐ์ดํ„ฐ ํ˜•์‹์ด T์ธ) ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•œ๋‹ค. ๊ทธ๋ž˜์„œ CoroutineScope.async์—์„œ๋Š” ์ฝ”๋ฃจํ‹ด ์ฝ”๋“œ ์† ์–ด๋–ค ๊ณ„์‚ฐ์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ํ•  ์ˆ˜ ์žˆ๋‹ค.
 
Defer์˜ ์‚ฌ์ „์  ์˜๋ฏธ๋Š” '๋ฏธ๋ฃจ๋‹ค, ์—ฐ๊ธฐํ•˜๋‹ค'๋‹ค. Deferred๋Š” ์ˆ˜๋™ํƒœ๋‹ˆ๊นŒ, '๋ฏธ๋ค„์ง„, ์—ฐ๊ธฐ๋œ' ์ •๋„์˜ ๋œป์ผํ…Œ๋‹ค. ๋ง ๊ทธ๋Œ€๋กœ Deferred<T> ์ธํ„ฐํŽ˜์ด์Šค๋Š” '๋ฏธ๋ค„์ง„, ์—ฐ๊ธฐ๋œ' ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค. ๊ทธ๋„ ๊ทธ๋Ÿด๊ฒŒ, CoroutineScope.async๊ฐ€ ์ˆ˜ํ–‰๋œ ์Šค๋ ˆ๋“œ์—์„œ ๊ณ„์‚ฐ์ด ์™„๋ฃŒ๋˜์–ด์•ผ๋งŒ ๋น„๋กœ์†Œ Deferred<T> ๊ฐ์ฒด๊ฐ€ ์žˆ๋Š” ์Šค๋ ˆ๋“œ๋กœ ๊ฒฐ๊ด๊ฐ’์ด ์ „๋‹ฌ๋  ๊ฒƒ์ด๊ธฐ์— ํ•„์—ฐ์ ์œผ๋กœ '๊ฐ’์ด ๋ฏธ๋ค„์งˆ ์ˆ˜๋ฐ–์—' ์—†๋Š” ๊ฒƒ์ด๋‹ค.
 

#4-3 Deferred.await()

'๋ฏธ๋ค„์ง„' ๊ฐ’์„ ๋ฐ›๋Š” ๋ฐฉ์‹์ด๋ฏ€๋กœ Deferred๊ฐ€ ์ €์žฅํ•˜ ๊ฐ’์„ ๋ฐ›๋Š” ๋ฉค๋ฒ„ ๋ฉ”์†Œ๋“œ ์ด๋ฆ„๋„ '๊ธฐ๋‹ค๋ฆฌ๋‹ค'๋ผ๋Š” ๋œป์˜ await๋‹ค. ์œ„ ์ฝ”๋“œ์—์„œ await()๊ฐ€ runBlocking { ... } ์•ˆ์— ๋“ค์–ด๊ฐ€ ์žˆ๋Š” ์ด์œ ๋Š” ์—ฌ๊ธฐ์— ์žˆ๋‹ค.
 

#5 Coroutine builder - CoroutineScope.produce

#5-1 ์ฝ”๋“œ

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*

fun produceNumbers(): ReceiveChannel<Int> {
    return CoroutineScope(Dispatchers.Default).produce {
        var x = 1
        while (true) {
            send(x++) // ๊ฐ’์„ ์ฑ„๋„๋กœ ๋ณด๋ƒ„
            delay(1000) // 1์ดˆ ๋Œ€๊ธฐ
        }
    }
}

fun main() {
    val numbers: ReceiveChannel<Int> = produceNumbers() // ReceiveChannel ์ƒ์„ฑ

    repeat(5) {
        runBlocking { println(numbers.receive()) } // ์ฑ„๋„์—์„œ ๊ฐ’ ์ˆ˜์‹ 
    }

    println("Done receiving")

    // ReceiveChannel์„ ๋‹ซ์Œ
    numbers.cancel()
}

/* ์ถœ๋ ฅ ๊ฒฐ๊ณผ
1
2
3
4
5
Done receiving
*/

produce๋Š” launch ๋ฐ async์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ˜„์žฌ ์Šค๋ ˆ๋“œ๋ฅผ Blockingํ•˜์ง€ ์•Š๊ณ , CoroutineContext์— ๋ช…์‹œ๋œ ์Šค๋ ˆ๋“œ์—์„œ ์ฝ”๋ฃจํ‹ด์„ ์‹คํ–‰ํ•œ๋‹ค. produce๋Š” async๋ฅผ ์‹ฌํ™”์‹œํ‚จ ํ˜•ํƒœ๋‹ค. async์€ ํ•œ ๋ฒˆ ๊ฐ’์„ returnํ•˜๊ณ  ๋๋‚˜๋Š” ๋ฐ ๋ฐ˜ํ•ด, produce๋Š” ๊ณ„์†ํ•ด์„œ return ๊ฐ’์„ ์ƒ์‚ฐ(produce)ํ•ด๋‚ธ๋‹ค. ๋”ฐ๋ผ์„œ ๋ณต์ˆ˜ ๊ฐœ์˜ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. CoroutineScope.produce๋Š” CoroutineScope.async๊ณผ ๋‹ฌ๋ฆฌ Deferred๊ฐ€ ์•„๋‹Œ ReceiveChannel<E> ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ returnํ•œ๋‹ค.
 

#5-2 ReceiveChannel<E> ์ธํ„ฐํŽ˜์ด์Šค

ReceiveChannal์€ ๋ณต์ˆ˜ ๊ฐœ์˜ ๊ฐ’์„ ์ œ๊ณตํ•˜๋Š” Deferred ๋น„์Šค๋ฌด๋ฆฌํ•œ ๊ฒƒ์ด๋ผ๋Š” ์ ์—์„œ, Deferred์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ถ€๋ชจ๊ฐ€ Job์ด์ง€ ์•Š์„๊นŒ ์ถ”์ธก๋˜์ง€๋งŒ ์‹ค์ œ ๊ทธ๋ ‡์ง„ ์•Š๋‹ค. ๊ทธ๋ž˜๋„ ๋Š๋‚Œ์œผ๋ก  ๋น„์Šทํ•˜๋‹ค. Job.cancel๊ณผ ๊ฑฐ์˜ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ReceiveChannel.cancel ๋ฉ”์†Œ๋“œ๋„ ์ง€๋‹ˆ๊ณ  ์žˆ๋‹ค.
 

#5-3 ReceiveChannel.receive()

receive()๋Š” ๋ฐ›์„ ๋•Œ๋งˆ๋‹ค ๊ฐ’์ด ๋‹ฌ๋ผ์ง„๋‹ค. ์œ„ ์ฝ”๋“œ์—์„œ receive()๊ฐ€ runBlocking { ... } ์•ˆ์— ๋“ค์–ด๊ฐ€ ์žˆ๋Š” ์ด์œ ๋Š” ์—ฌ๊ธฐ์— ์žˆ๋‹ค.

#6 CoroutineScope ์ƒ๋žต

#6-1 CoroutineScope ์ค‘์ฒฉ

import kotlinx.coroutines.*

suspend fun main() {
    val myJob = CoroutineScope(Dispatchers.Default).launch {
        println("I'm in launch() function on ${Thread.currentThread().name} thread")
        println("Async will be started after 2 seconds")
        delay(2000)

        val asyncResult = CoroutineScope(Dispatchers.Default).async {
            println("I'm in async() function on ${Thread.currentThread().name} thread")
            println("Calculating...")
            delay(3000)
            return@async 777
        }

        println("asyncResult is ${asyncResult.await()}")
    }

    myJob.join()
}

/* ์ถœ๋ ฅ ๊ฒฐ๊ณผ
I'm in launch() function on DefaultDispatcher-worker-1 thread
Async will be started after 2 seconds
I'm in async() function on DefaultDispatcher-worker-2 thread
Calculating...
asyncResult is 777
*/

์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ฝ”๋ฃจํ‹ด์„ ์ค‘์ฒฉํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ์ด์™€ ๊ฐ™์ด CoroutineScope(CoroutineContext)๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ์ƒ๋‹นํžˆ ํ•ด์นœ๋‹ค. fun ์•ž์— ์žˆ๋Š” suspend ํ‚ค์›Œ๋“œ๋Š” ์—ฌ๊ธฐ์—์„œ ์„ค๋ช…ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ผ๋‹จ ๋ณธ ๊ฒŒ์‹œ๊ธ€์—์„  ๋ฌด์‹œํ•˜๊ณ , CoroutineScope์˜ ์ค‘์ฒฉ์—๋งŒ ์ง‘์ค‘ํ•˜์ž.

 

#6-2 CoroutineScope ์ƒ๋žต - CoroutineContext ์•”์‹œ์  ์ƒ์†

import kotlinx.coroutines.*

suspend fun main() {
    val myJob = CoroutineScope(Dispatchers.Default).launch {
        println("I'm in launch() function on ${Thread.currentThread().name} thread")
        println("Async will be started after 2 seconds")
        delay(2000)

        val asyncResult = async {
            println("I'm in async() function on ${Thread.currentThread().name} thread")
            println("Calculating...")
            delay(3000)
            return@async 777
        }

        println("asyncResult is ${asyncResult.await()}")
    }

    myJob.join()
}

/* ์ถœ๋ ฅ ๊ฒฐ๊ณผ
I'm in launch() function on DefaultDispatcher-worker-1 thread
Async will be started after 2 seconds
I'm in async() function on DefaultDispatcher-worker-2 thread
Calculating...
asyncResult is 777
*/

#6-1๊ณผ ๋™์ผํ•œ ๋™์ž‘์„ ํ•˜๋Š” ์ฝ”๋“œ๋‹ค. ์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” ์–ด๋–ค CoroutineScope ๋‚ด์—์„œ Builder๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ CoroutineScope(CoroutineContext)๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฝ”๋“œ์—์„œ async()์˜ CoroutineScope๋Š” launch()์™€ ๋™์ผํ•œ ๊ฒƒ์„ ์ƒ์†๋ฐ›์•„ ์‚ฌ์šฉํ•œ๋‹ค.

 

#6-3 CoroutineScope ์ƒ๋žต - CoroutineContext ๋ณ€๊ฒฝํ•˜๊ธฐ

suspend fun main() {
    val myJob = CoroutineScope(Dispatchers.Default).launch {
        println("I'm in launch() function on ${Thread.currentThread().name} thread")
        println("Async will be started after 2 seconds")
        delay(2000)

        val asyncResult = async(Dispatchers.IO + CoroutineName("myAsync")) {
            println("I'm in async() function on ${Thread.currentThread().name} thread")
            println("Calculating...")
            delay(3000)
            return@async 777
        }

        println("asyncResult is ${asyncResult.await()}")
    }

    myJob.join()
}

/* ์ถœ๋ ฅ ๊ฒฐ๊ณผ
I'm in launch() function on DefaultDispatcher-worker-1 thread
Async will be started after 2 seconds
I'm in async() function on DefaultDispatcher-worker-2 thread
Calculating...
asyncResult is 777
*/

CoroutineScope๋Š” ์ƒ๋žตํ•˜๋ฉด์„œ, CoroutineContext๋งŒ ๋ณ€๊ฒฝํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๋ฐ”๋กœ, Builder์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ CoroutineContext๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ๋œ๋‹ค. ๋ฌธ๋ฒ•์€ CoroutineScope์— CoroutineContext๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๋‹ค. Dispatchers.Default์™€ Dispatchers.IO์˜ ์Šค๋ ˆ๋“œ๋ช…์ด ๊ฐ™์€ ์ด์œ ๋Š” ์ด ๋งํฌ์˜ #3-2์— ์žˆ๋‹ค.

 

#6-4 ์ƒ๋žต์€ ๊ฐ€๋…์„ฑ๋งŒ์„ ์œ„ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค

 

[Kotlin] Coroutines - ํ•œ Scope ๋‚ด์—์„œ์˜ ๊ณ„์ธต ๊ด€๊ณ„

#1 ์ด์ „ ๊ธ€ [Kotlin] Coroutines - Coroutine builder#1 Coroutine builder kotlinx-coroutines-coreCore primitives to work with coroutines. Coroutine builder functions: Coroutine dispatchers implementing CoroutineDispatcher: More context elements: Synchron

kenel.tistory.com

์‚ฌ์‹ค, #6-1๊ณผ #6-2๋Š” ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋‹ค. ์ฆ‰, CoroutineScope์˜ ์ƒ๋žต์€ ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ ์™ธ์˜ ์˜๋ฏธ๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค๋Š” ๋ง์ด๋‹ค. ๊ทธ๊ฒƒ์€ ๋ฐ”๋กœ, ํ•˜๋‚˜์˜ CoroutineScope ๋‚ด์—์„œ์˜ ๊ณ„์ธต(๋ถ€๋ชจ-์ž์‹) ๊ด€๊ณ„์˜ ๊ตฌํ˜„์ด๋‹ค. #6-2 ์ฝ”๋“œ์—์„œ launch๋Š” ๋ถ€๋ชจ, async์€ ์ž์‹์ด ๋œ๋‹ค. ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์œ„ ๊ฒŒ์‹œ๊ธ€์—์„œ ๋‹ค๋ฃฌ๋‹ค.

 

#7 ์š”์•ฝ

์ฝ”๋ฃจํ‹ด ๋นŒ๋” launch, async, produce ๊ฐ๊ฐ์˜ ๋ฐ˜ํ™˜ํ˜•์€ Unit, Deferred<T>, ReceiveChannel<E>๋‹ค.