multithreading - 为什么 kotlin 协程被认为是轻量级的?

标签 multithreading kotlin kotlin-coroutines

如果协程仍然使用线程并行运行代码,为什么它被认为是轻量级的?
据我了解,kotlin 的 suspend函数由编译器转换为状态机,其中每个分支都可以在开发人员定义的相同或不同线程上运行。协程构建器,例如 launch{} ,对此负责,CoroutineContext是定义要运行的线程的内容。
通过将代码块发送到利用相同线程的线程池来实现并行性
有一个关于 100k 协程和 100k 线程的基准测试,其中协程没有问题地通过并且线程抛出异常(可能是 OutOfMemory)。它让我想到我在这里遗漏了一些东西。
你能帮我理解这里遗漏了什么,是什么让协同程序并行运行代码块 100k 而不会像线程那样超出内存限制?

最佳答案

指向article

Every Thread has its own stack, typically 1MB. 64k is the least amount of stack space allowed per thread in the JVM while a simple coroutine in Kotlin occupies only a few dozen bytes of heap memory.


Coroutine Dispatcher 有一个限制,只能创建一定数量的线程。
Dispatchers.IO有 64 个线程的限制,Dispatchers.Default您的处理器上的内核数量有限制(2、4、6、8 等)Dispatchers.Unconfined无法创建它在其他调度程序先前创建的线程上运行的新线程,这里是证明:具有 10 毫秒 sleep 的 500 个操作大约需要 5 秒(单线程,因为它不能产生新线程)try it yourself .
协程粘在一个线程上,一旦达到暂停点,它就会离开线程并释放它,让它在等待时接收另一个协程。这种方式使用更少的线程和更少的内存使用,可以完成很多并发工作。
协程通过像对象 Continuation 这样的回调来管理暂停和恢复。它作为最后一个参数添加到标有 suspend 的函数中编译时的关键字与其他对象一样位于堆中并负责协程的恢复,因此 RAM 中不需要数千 MB 的空间来保持所有线程的事件。使用 CommonPool 最多创建典型的 60-70 个线程并被重用(如果创建了新的协程,它会等到另一个完成)。

关于multithreading - 为什么 kotlin 协程被认为是轻量级的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63719766/

相关文章:

c# - 如何进行C#异步编程?

multithreading - 如何安全地将新的键值对添加到原生 map 中

objective-c - 如何在 objective-c 中编写非阻塞方法

kotlin - 如何在离线环境下运行Gradle kotlin-dsl插件?

android - 如何在android中删除注释@InternalCoroutinesApi

iOS AFNetworking 阻塞主线程

maven - Kotlin 多模块项目依赖在测试生命周期中未解决

generator - 作为扩展函数调用的序列生成器失败并显示 "receiver type mismatch"

java - 如何为 Retrofit 中的挂起功能创建调用适配器?

android - 与 SupervisorJob 的协程 - 取消行为