为什么Kotlin协程会阻止此代码?

问题描述

为什么此代码永远不会打印Hello World?

runBlocking(Dispatchers.Main) {
    launch {
        delay(1)
        println("Hello world")
    }
}

但这会打印

runBlocking {
    launch {
        delay(1)
        println("Hello world")
    }
}

解决方法

在我看到的第一个示例中,该应用程序完全冻结了(当在按钮单击侦听器中使用时)。

问题是您造成了僵局:

  1. Dispatchers.Main通过将协程发布(调度)到主应用程序循环器中来工作
  2. runBlocking阻止主应用程序线程
  3. 主循环程序永远不会运行已发布的协程,因为它正在等待runBlocking完成

您可以使用Dispatchers.Main.immediate来稍微缓解“问题”,它是基本调度程序的一个更聪明的版本-如果它已经在主线程上运行并在其中执行,它不会将协程发布到主循环程序中-地方。

这将允许您运行launch块,但是delay将再次发布协程以继续在主循环程序上执行并导致另一个死锁。

第二个代码示例没有问题,因为在那里运行的协程不与主线程进行交互(除了runBlocking之外)。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...