【问题标题】:runBlocking Coroutine doesn't block GlobalScope.launch (?)runBlocking Coroutine 不会阻止 GlobalScope.launch (?)
【发布时间】:2019-08-28 07:03:28
【问题描述】:

Kotlin 的 runBlocking Coroutine 应该阻塞当前线程,直到块内的 Coroutine 完成执行,但当块内的 Coroutine 是 GlobalScope.launch 时,它似乎没有这样做

我正在尝试了解 Kotlin 的协程如何工作并阅读此处的文档 - https://kotlinlang.org/docs/reference/coroutines/basics.html

在示例中 -

fun main() = runBlocking<Unit> { // start main coroutine
    GlobalScope.launch { // launch 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 的主线程会阻塞,直到 runBlocking 内的协程完成”。如果是这样,那么为什么我们需要两秒延迟在 runBlocking 结束时阻塞主线程?为什么在 GlobalScope.launch 完成之前 runBlocking 不会阻塞主线程?

但是,下面的内部 runBlocking 会阻塞主线程,直到延迟函数完成。这里有什么区别?为什么在 GlobalScope.launch 以类似的方式完成之前,上述阻塞主线程中的 runBlocking 不运行-

fun main(){ // start main coroutine
    GlobalScope.launch { // launch new coroutine in background and continue
        delay(1000L)
        println("World!")
    }
    println("Hello,") // main coroutine continues here immediately
    runBlocking{
     delay(2000L)      // delaying for 2 seconds to keep JVM alive
    }
}

我希望当 main 函数被包装在 runBlocking 协程中时,应该阻塞主线程,直到 GlobalScope.launch 完成其执行。

【问题讨论】:

  • 我找到了答案!看起来 GlobalScope.launch 启动的协程在全局范围内运行,而主协程不会等到它完成,因为它没有在其范围内启动。如果将 GlobalScope.launch 更改为简单地启动,则协程将在主协程范围内启动,因此主线程将被阻塞直到完成。
  • GlobalScope.launch { }.join() 或异步{ }.await() stackoverflow.com/a/48079738/10259099

标签: kotlin kotlin-coroutines


【解决方案1】:

作用域中的协程将阻塞,直到同一作用域中的所有子 (jobs) 完成为止。然而,在另一个范围内显式启动协程不会使它们成为真正的孩子,因此它们不会被等待。

这篇文章还提供了一些关于这个特殊案例的信息:https://medium.com/@elizarov/the-reason-to-avoid-globalscope-835337445abc

【讨论】:

    猜你喜欢
    • 2019-07-17
    • 1970-01-01
    • 2020-11-08
    • 2020-08-06
    • 2023-03-03
    • 2019-01-28
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多