Hanbit the Developer

Kotlin Documentation | Coroutines basics 본문

Mobile/Kotlin

Kotlin Documentation | Coroutines basics

hanbikan 2023. 5. 24. 16:49

Kotlin Documentation 시리즈에 대해

Category: Official libraries - Coroutines

문서 링크: https://kotlinlang.org/docs/coroutines-basics.html


Your first coroutine

fun main() = runBlocking { // this: CoroutineScope
    launch { // launch a new coroutine and continue
        delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
        println("World!") // print after delay
    }
    println("Hello") // main coroutine continues while a previous one is delayed
}
Hello
World!

*’suspend’ function 의미 관련 인용: “delay is a special suspending function. It suspends the coroutine for a specific time.”

Structured concurrency

특정 CoroutineScope 내에서 실행된 새 코루틴은 lifetime이 상위 코루틴 내로 제한된다. outer scope는 모든 children coroutines가 완료될 때까지 완료될 수 없다.

이는 메모리 릭을 방지하며 내부 코드의 에러가 날아가지 않고 적절히 처리되는 것을 보장한다.

Extract function refactoring

Suspend fun은 코루틴 내에서 일반적인 함수처럼 쓰일 수 있으며, 다른 suspend fun(delay() 등)을 사용할 수 있다.

fun main() = runBlocking { // this: CoroutineScope
    launch { doWorld() }
    println("Hello")
}

// this is your first suspending function
suspend fun doWorld() {
    delay(1000L)
    println("World!")
}

Scope builder

  • runBlocking(): 새 코루틴을 실행시키고 블럭을 마칠 때까지 현재 쓰레드를 block시키는 regular function이다.
  • coroutineScope(): 새 코루틴 스코프를 생성하고 블럭을 실행시키는 suspend function이다. 바깥 스코프의 컨텍스트를 상속하지만 컨택스트의 Job을 오버라이드한다. 주로 여러 코루틴을 실행시키고 모든 동작이 마치기를 원할 때 사용한다:
suspend fun doSomeWork() = coroutineScope {
    launch { /* do some work */ }
    launch { /* do some other work */ }
    // wait for all launched coroutines to complete
}

*유사한 네이밍의 CoroutineScope(Dispatchers.IO).launch {}은 새 코루틴을 실행시키는 regular function이다.

 

Scope builder and concurrency

// Sequentially executes doWorld followed by "Done"
fun main() = runBlocking {
    doWorld()
    println("Done")
}

// Concurrently executes both sections
suspend fun doWorld() = coroutineScope { // this: CoroutineScope
    launch {
        delay(2000L)
        println("World 2")
    }
    launch {
        delay(1000L)
        println("World 1")
    }
    println("Hello")
}
Hello
World 1
World 2
Done

An explicit job

코루틴 빌더인 launch는 Job을 반환한다. Job을 통해 실행된 코루틴을 다루거나 코루틴의 종료를 기다릴 수 있다.

val job = launch { // launch a new coroutine and keep a reference to its Job
    delay(1000L)
    println("World!")
}
println("Hello")
job.join() // wait until child coroutine completes
println("Done")
Hello
World!
Done

Coroutines are light-weight

아래와 같이, 쓰레드였다면 리소스 제한에 걸렸을 코드도 코루틴을 사용하면 매우 적은 메모리로 실행할 수 있다. 코루틴은 경량화되어 있기 때문이다.

fun main() = runBlocking {
    repeat(50_000) { // launch a lot of coroutines
        launch {
            delay(5000L)
            print(".")
        }
    }
}