Coroutine Basics

Kotlin 공식문서

Your first coroutine

GlobalScope.launch { // launch a new coroutine in background and continue
    delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
    println("World!") // print after delay
}
println("Hello,") // main thread continues while coroutine is delayed
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive

GlobalScope라는 CoroutineScope에서 CoroutineBuilder인 launch를 통해 Coroutine을 만들었다.

Bridging blocking and non-blocking worlds

runBlocking { // start main coroutine (blocks thread)
    GlobalScope.launch { // launch a new coroutine in background and continue
        delay(1000L)
        println("World!")
    }
    println("Hello,") // main coroutine continues here immediately
    delay(2000L)      // delaying for 2 seconds to keep JVM alive
}
  • runBlocking : Runs a new coroutine and blocks the current thread interruptibly until its completion. This should not be used from a coroutine.

Waiting for a Job

val job = GlobalScope.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
  • join()으로 non-blocking 하는 방식으로 job의 완료까지 wait 시킬 수 있다.

Structured concurrency

  • 뜻 : 명확한 진입 및 종료지점이 있고, 종료 전에 생성된 모든 스레드가 완료된다.
  • GlobalScope에 Coroutine을 생성하는 것은 특별한 목적이 있는게 아니면 좋지 않다.
  • 수명이 Global이어서 reference를 가지고 끝까지 관리해야하기 때문이다.
runBlocking {
    launch { // launch a new coroutine in the scope of runBlocking
        delay(1000L)
        println("World!")
    }
    println("Hello,")
}
  • outer coroutine(여기선 runBlocking) does not complete until all the coroutines launched in its scope complete.
  • 그러므로 위의 launch는 join하지 않아도 World가 출력된다.

Scope Builder

runBlocking {
    launch { 
        delay(200L)
        println("Task from runBlocking")
    }
    
    coroutineScope { // Creates a coroutine scope
        launch {
            delay(500L) 
            println("Task from nested launch")
        }
    
        delay(100L)
        println("Task from coroutine scope") // This line will be printed before the nested launch
    }
    
    println("Coroutine scope is over") // This line is not printed until the nested launch completes
}
  • coroutineScope also waits for their body and all its children to complete.

Extract function refactoring

  • 코드 일부분을 extract해서 refactoring 하려면 함수를 만들 때 suspend 키워드를 붙여야한다.

Coroutines ARE light-weight

  • 코루틴은 경량 스레드다.
  • 이전 발표에서 봤던 10만개 점찍기다. (Coroutines vs Thread)

Global coroutines are like daemon threads

  • 데몬 스레드 : 주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드
GlobalScope.launch { // Global Scope!!
    repeat(1000) { i ->
        println("I'm sleeping $i ...")
        delay(500L)
    }
}

위 코드를 실행하면 어디서 실행했든간에 앱이 꺼지지 않는한 동작할 것이다. (별도 캔슬 등 안하면)

앞서 몇개 들었던 발표들 때문인지 공식문서 첫 페이지라서 그런지 내용은 쉬웠다.

좋은 웹페이지 즐겨찾기