Kotlin Flow的collect方法执行时是否会阻塞当前协程?
结论
Flow的collect是挂起函数,不会阻塞操作系统线程,仅会挂起它当前所属的协程,同线程下的其他协程不会受到影响。
代码A现象解释
你在代码A中所有逻辑都运行在runBlocking启动的主协程中,没有开启其他子协程:
- 执行到
flow.collect时,主协程被挂起,等待Flow全部元素发射、处理完成后才会恢复执行 - 后续的
println("Calling collect again...")自然要等到collect执行完才会运行,所以你得到结果A是符合预期的
你想要的结果B不可能在现有代码结构下实现,因为你没有为collect单独分配协程,主协程被挂起后后续代码只能排队等待。如果要得到结果B,只需把collect逻辑放到独立的子协程中运行即可:
fun main() = runBlocking<Unit> { println("Calling simple function...") val flow = simple() println("Calling collect...") launch { // 启动单独子协程跑collect flow.collect { value -> println(value) } } println("Calling collect again...") }
代码1现象解释
代码1刚好验证了collect不会阻塞线程的特性:
- 你通过
launch开启了独立的子协程运行打印"I'm not blocked"的逻辑,collect运行在主协程中 - 两个协程共享
runBlocking的调度线程,delay和collect的挂起逻辑都会让出执行权,所以两个协程会交替执行,最终得到你看到的结果1,完全没有出现collect阻塞线程卡住另一个协程的情况。
内容的提问来源于stack exchange,提问作者HelloCW
相关产品推荐
相关产品推荐

