【问题标题】:Why do kotlin coroutines block this code?为什么 kotlin 协程会阻塞这段代码?
【发布时间】:2020-08-11 16:00:23
【问题描述】:
为什么这段代码永远不会打印 Hello World?
runBlocking(Dispatchers.Main) {
launch {
delay(1)
println("Hello world")
}
}
但这会打印出来
runBlocking {
launch {
delay(1)
println("Hello world")
}
}
【问题讨论】:
标签:
android
kotlin
kotlin-coroutines
【解决方案1】:
从我看到的第一个示例完全冻结应用程序(在按钮点击侦听器中使用时)。
问题是你造成了死锁:
-
Dispatchers.Main 通过将协程发布(调度)到主应用程序循环器来工作
-
runBlocking 阻塞主应用线程
- 主循环器将永远无法运行已发布的协程,因为它正在等待
runBlocking 完成
您可以通过使用Dispatchers.Main.immediate 稍微缓解“问题”,而不是使用更智能的基本调度程序版本 - 如果协程已经在主线程上运行并就地执行,它不会将协程发布到主循环器.
这将允许您运行launch 块,但是delay 将再次发布协程以继续主循环并导致另一个死锁。
第二个代码示例没有问题,因为在那里运行的协程不与主线程交互(runBlocking 除外)。
【讨论】:
-
注意runBlocking 通常应该使用never(在非测试代码中)可能很重要。