协程延续内部如何工作?

Anu*_*Lal 4 concurrency android kotlin kotlin-coroutines

我已经使用协程工作了几个星期,有时很难理解线程并发和协程并发之间的真正工作差异。

挂起函数内部如何工作?延续块如何帮助暂停后恢复计算。协程内代码行的顺序计算如何不阻塞线程?它比线程并发更好在哪里?

Mar*_*nik 6

挂起函数内部如何工作?

简而言之,在 Java 平台上,asuspend fun编译成与普通函数显着不同的字节码。它接收一个隐藏的额外参数(延续),创建自己的延续对象,并且函数的整个主体(大约)实现为一个大switch语句,允许函数在恢复时跳转到主体的中间。

当 asuspend fun挂起时,底层 Java 方法实际上返回。返回值是一个特殊的COROUTINE_SUSPENDED单例对象,框架知道如何解释它。它本身有责任suspend fun将延续对象保存在函数结果准备好时可以访问的地方。

官方文档对这些细节有很好的深入描述。

延续块如何帮助暂停后恢复计算。

这和我上面说的有关,它suspend fun本身负责确保稍后恢复。它必须在函数提供的块内执行此操作suspendCoroutineOrReturn。用户代码不会直接调用它,而是更高级的类似物suspendCoroutinesuspendCancellableCoroutine. 这些接管了在适当的线程上恢复协程的关注,开发人员只负责确保在continuation.resume()结果可用时调用它。这通常发生在您传递给异步调用的回调中。

您可以研究这个答案,它试图在一个独立的示例中解释暂停恢复机制。

协程内代码行的顺序计算如何不阻塞线程?

因为它实际上编译为从函数返回,然后通过跳转到函数体的中间来恢复。

它比线程并发更好在哪里?

本机线程是重量级资源,需要时间来创建和销毁。协程的重量要轻得多,因此您可以更快地启动更多协程。