android - 为什么 kotlin 协程会阻塞这段代码?
问题描述
为什么这段代码永远不会打印 Hello World?
runBlocking(Dispatchers.Main) {
launch {
delay(1)
println("Hello world")
}
}
但这会打印
runBlocking {
launch {
delay(1)
println("Hello world")
}
}
解决方案
从我看到的第一个示例完全冻结应用程序(在按钮单击侦听器中使用时)。
问题是你造成了死锁:
Dispatchers.Main
通过将协程发布(调度)到主应用程序循环器来工作runBlocking
阻塞主应用程序线程- main looper 永远不会运行发布的协程,因为它正在等待
runBlocking
完成
您可以通过使用更智能的基本调度程序版本来稍微缓解“问题” Dispatchers.Main.immediate
- 如果它已经在主线程上运行并就地执行它,它不会将协程发布到主循环器。
这将允许您运行该launch
块,但delay
将再次发布协程以在主循环器上继续并导致另一个死锁。
第二个代码示例没有问题,因为在那里运行的协程不与主线程交互(除此之外runBlocking
)。
推荐阅读
- javascript - 如何在 JavaScript 中用日期字符串包装数组值
- python - Python - 将数据框的输出保存到 excel 时出错
- r - 如何在 SQLDeveloper 中将超过 200000 条记录从表导出到 CSV
- c# - 如何在wpf窗口中为所有Itextsharp pdf页面打印水印
- javascript - Json解析器和循环方案
- selenium - 如果完成测试所用的时间超过 30 秒,则测试脚本失败
- java - 替换java中的多行字符串
- azure - 如何使用有状态集 kubernetes 将 cassandra 数据位置挂载到 azure 文件共享
- java - AlertDialog 未从另一个非活动类中显示
- security - QnAmaker 知识库隐私和安全