几个星期以来,我一直在使用协同机制,有时很难理解线程并发和协同并发之间真正的工作区别。
挂起功能是如何在内部工作的?连续块如何帮助恢复暂停后的计算。协同线内代码行的顺序计算如何不阻塞线程?那么它如何比线程并发更好呢?
发布于 2019-11-27 09:34:17
挂起功能是如何在内部工作的?
简单地说,在Java平台上,suspend fun编译成与普通函数截然不同的字节码。它接收一个隐藏的额外参数(延拓),创建自己的延续对象,整个函数体被实现(大约)为一个大型switch语句,该语句允许函数在恢复时跳入主体的中间。
当suspend fun挂起时,底层的Java方法实际上会返回。返回值是一个特殊的COROUTINE_SUSPENDED单例对象,框架知道如何解释该对象。当函数的结果准备就绪时,suspend fun本身有责任将延续对象保存在可以访问的地方。
正式文件对这些细节有很好的深入描述.
连续块如何帮助恢复暂停后的计算。
这与我前面所说的有关,即suspend fun本身负责确保稍后恢复。它必须在函数suspendCoroutineOrReturn提供的块中这样做。用户代码不是直接调用它,而是更高级别的类比suspendCoroutine和suspendCancellableCoroutine.它们接管了在适当线程上恢复协同线的问题,开发人员只负责确保在continuation.resume()可用时调用该结果。这通常发生在传递给异步调用的回调中。
您可以学习试图在一个独立的示例中解释挂起-恢复机制的这个答案。
协同线内代码行的顺序计算如何不阻塞线程?
因为它实际上编译为从函数返回,然后通过跳入函数体的中间进行恢复。
那么它如何比线程并发更好呢?
本机线程是重量级资源,需要时间来创建和销毁。Coroutines的重量要轻得多,因此你可以启动更多的,更快的。
发布于 2019-11-24 08:33:11
内部工作在最初的设计文档https://github.com/Kotlin/KEEP/blob/master/proposals/coroutines.md中进行了解释,其中有一节是关于“实现细节”的。
https://stackoverflow.com/questions/59005067
复制相似问题