首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对于现实世界的Android开发来说,协程到底有多“轻量级”?

对于现实世界的Android开发来说,协程到底有多“轻量级”?
EN

Stack Overflow用户
提问于 2020-05-07 17:28:15
回答 2查看 189关注 0票数 3

当您开始学习Kotlin协程时,您看到的第一个示例之一是可以启动数十万个协程,但在尝试对线程执行相同的操作时会遇到OutOfMemory异常。

虽然这个例子很“酷”,但我不认为它对现实世界的Android应用程序开发有什么用处,甚至有点误导。当然,您可以启动数十万个只做delay()的协程,但在现实中,您要么启动执行某种IO或某种计算的协程。

例如,如果您启动了数十万个协程,并且每个协程都使用Retrofit执行一个网络请求,那么它不会比传统地使用没有协程的Retrofit更轻量级,因为okhttp仍然会为每个请求阻塞一个线程。

当您使用协程进行计算时,情况也是如此。那么它也不是更轻量级的,因为执行计算的线程会被阻塞,直到它们完成。

那么,我的假设是正确的吗?如果没有非阻塞IO库的存在,我的应用程序不会因为使用协程而变得更高效或更“轻量级”,还是我错过了什么?

EN

回答 2

Stack Overflow用户

发布于 2020-05-07 19:08:27

当然,您可以启动数十万个只做

()的协程,但实际上,您要么启动执行某种IO或某种计算的协程。

不一定。协程对于重新组织其他类型的代码也很有用,比如working with views

例如,如果你启动了成百上千的协程,并且每个协程都执行了一个带有

的网络请求,那么它不会比没有协程的传统的Retrofit更轻量级,因为okhttp仍然会为每个请求阻塞一个线程。

我猜你是想说OkHttp使用了一个线程池。这绝对是事实。

当你在协程中进行计算时,

也是如此。那么它也不是更轻量级的,因为执行计算的线程会被阻塞,直到它们完成。

这是您原始段落中的OutOfMemoryError场景,如果您每次计算都要创建单独的线程。

协程调度程序是基于线程池的。“成百上千的协程”场景最终将不使用线程池与使用线程池进行了比较。所以,是的,“几十万个协程”的比较并不显著,因为还有其他使用线程池的方式。

票数 4
EN

Stack Overflow用户

发布于 2020-05-07 19:22:45

您部分正确,打开多个阻塞IO请求将排队到Dispatchers.IO中,如果最大请求数超过64 ( IO Dispatcher上的最大线程数),它们将按顺序执行,即随着线程将被释放而逐个执行。

协程并不神奇,它们只是通过一个在幕后充当回调处理程序的Continuation将回调转换成看起来像是连续的代码。

现实应用程序中的协程通常受益于更改线程、冷流、通道的简单性,从而挂起的协程接收值在恢复之前不会实质上占用线程。

虽然RxJava做了同样的事情,但协同例程的基准测试表明,它消耗的内存更少,完成check benchmarks here所需的时间也明显更少。

您还可以使用协程通过使用堆内存而不是堆栈来实际实现深度递归,请参阅Roman's elizarov implementation of deep recursion using the coroutines它们是否足够轻量级?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61654349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档