首页 > 解决方案 > kotlin 协程是否会阻塞 IO 上的线程直到它完成?

问题描述

据我了解,阻塞 IO 的协程会阻塞它正在运行的线程。该线程将被操作系统挂起,以便稍后重新调度。

这是否意味着如果我有一个包含 50 个线程和 50 个并发协程在每个线程上执行 IO 的线程池,它们将有效地阻塞线程池中的所有线程,直到其中至少一个线程完成 IO 操作?

或者是否有一种机制可以将导致阻塞 IO 的协程停放在某种队列上?

标签: kotlinkotlinx.coroutines

解决方案


如果我有一个有 50 个线程和 50 个并发协程在每个线程上执行 IO 的线程池,它们会有效地阻塞线程池中的所有线程,直到其中至少一个线程完成 IO 操作?

是的。无法绕过阻塞方法阻塞调用线程的事实。协程并不是改变这种情况的魔杖。

协程的价值在于您可以通过使用非常自然的编程模型将阻塞操作从 UI 线程卸载到线程池。代码看起来就像一个以返回值完成的普通函数调用,但实际上协程挂起以便其他 UI 事件处理程序可以运行。

然而,协同程序在处理基于回调的非阻塞、异步 API 时真正闪耀。在这种情况下,您可以在 UI 线程上获得可以描述为“单线程并发”的行为。并发通过交错执行事件处理程序来工作。与本机线程的主要区别在于,交错不依赖于在他们不知情的情况下抢先挂起线程。相反,协程本身必须要求暂停。


推荐阅读