Kotlin/協程基礎

維基教科書,自由的教學讀本

第一個協程[編輯]

運行以下程式

import kotlinx.coroutines.*

fun main() {
    GlobalScope.launch { // 背景開啟新協程
        delay(1000L) // 不中斷其他程序的 delay 一秒,注意 delay 函式的預設單位是毫秒
        println("World!") // 在一秒後印出
    }
    println("Hello,") // 主線程在協程 delay 時繼續運作,並印出「Hello,」
    Thread.sleep(2000L) // 阻斷主線程兩秒,以維持 JVM 運作
}

會印出

Hello,
World!

Bridging blocking and non-blocking worlds[編輯]

等待開工[編輯]

Delaying for a time while another coroutine is working is not a good approach. Let's explicitly wait (in a non-blocking way) until the background Job that we have launched is complete:

val job = GlobalScope.launch { // 開啟新協程並記錄在 job 常數上
    delay(1000L)
    println("World!")
}
println("Hello,")
job.join() // 等待子協程結束

Now the result is still the same, but the code of the main coroutine is not tied to the duration of the background job in any way. Much better.

結構化的併發[編輯]

Scope builder[編輯]

Extract function refactoring[編輯]

協程是輕量的[編輯]

和線程相比,協程是非常輕量的。如果我們嘗試運行以下程式

import kotlinx.coroutines.*

fun main() = runBlocking {
    repeat(100_000) { // 打開很多協程
        launch {
            delay(1000L)
            print(".")
        }
    }
}

我們開啟了十萬個協程,每秒之後,每個協程都印出一個點。

如果我們改用線程做一樣的事,會怎樣呢?正常情況下你的電腦應該會跳出記憶體不夠的錯誤。

所以我們可以知道,協程是比起線程更輕量的。

全域協程有點像是守護行程[編輯]

參考資料[編輯]

https://kotlinlang.org/docs/reference/coroutines/basics.html