了解 runBlocking 和 coroutineScope 之间的行为差​​异

Understanding difference in behavior between runBlocking and coroutineScope

在 Kotlin Coroutines 指南中,here,在解释 runBlockingcoroutineScope 之间的区别时,它说:

... The main difference is that the runBlocking method blocks the current thread for waiting, while coroutineScope just suspends, releasing the underlying thread for other usages. ...

这是可以理解的。但是,在此处列出的示例代码中:

import kotlinx.coroutines.*

fun main() = runBlocking { // this: CoroutineScope
    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
}

产生以下输出:

Task from coroutine scope
Task from runBlocking
Task from nested launch
Coroutine scope is over

coroutineScope 替换为 runBlocking 为:

import kotlinx.coroutines.*

fun main() = runBlocking { // this: CoroutineScope
    launch { 
        delay(200L)
        println("Task from runBlocking")
    }
    
    runBlocking { // instead of coroutineScope, previously
        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
}

输出没有任何变化。我希望它产生以下输出,因为嵌套的 runBlocking 会阻塞,直到它的块完成,包括所有子协程:

Task from coroutine scope
Task from nested launch
Task from runBlocking
Coroutine scope is over

有人可以解释这种行为吗?我在这里监督什么?

runBlocking 只会阻塞当前线程,直到 block 传递给它 returns。它不会影响 block 的执行方式。

在一个 runBlocking 中有一个 runBlocking 是..不寻常的。更常见的是 runBlocking 只是最外层的东西。事实上,runBlocking 的实现将使用外部 runBlocking 的事件循环而不是创建一个新的事件循环,因此在这种情况下它实际上 表现得像 coroutineScope。

来源:https://github.com/Kotlin/kotlinx.coroutines/blob/dda99e21f45f65eb540ccf4d5e82faf7559bc9e5/kotlinx-coroutines-core/jvm/src/Builders.kt#L46