我已经使用协程几个星期了,有时很难理解线程并发和协程并发之间真正的工作区别。
暂停函数在内部是如何工作的?继续 block 如何帮助在暂停后恢复计算。 协程中代码行的顺序计算如何不阻塞线程?它比线程并发性好在哪里?
最佳答案
How suspend functions works internally?
简而言之,在 Java 平台上,suspend fun
编译成与普通函数截然不同的字节码。它接收一个隐藏的额外参数(continuation),创建自己的 continuation 对象,并且函数的整个主体(大约)实现为一个大的 switch
语句,允许函数跳到中间恢复时的 body 。
当 suspend fun
挂起时,底层 Java 方法实际上会返回。返回值是一个特殊的 COROUTINE_SUSPENDED
单例对象,框架知道如何解释它。 suspend fun
本身负责将延续对象保存在函数结果准备就绪时可以访问的位置。
official documentation对这些细节都有很好的深入描述。
How is continuation block helping in resuming the computation after suspension.
这与我上面所说的有关,suspend fun
本身负责确保稍后恢复。它必须在函数 suspendCoroutineOrReturn
提供的 block 内执行此操作。用户代码不会直接调用它,而是更高级的类比 suspendCoroutine
和 suspendCancellableCoroutine
。这些接管了在适当线程上恢复协程的关注,开发人员仅负责确保 continuation.resume()
在结果可用时被调用。这通常发生在您传递给异步调用的回调中。
可以学习this answer试图在一个独立的示例中解释挂起-恢复机制。
How is sequential computation of the line of code inside coroutine not blocking the thread?
因为它实际上编译为从函数返回,然后通过跳转到函数体的中间来恢复。
and how is it better than thread concurrency?
native 线程是重量级资源,需要时间来创建和销毁。协程的重量要轻得多,因此您可以更快地启动更多协程。
关于android - Coroutine Continuation 在内部是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59005067/