首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么kotlin协程被称为异步?

为什么kotlin协程被称为异步?
EN

Stack Overflow用户
提问于 2021-09-17 11:23:07
回答 2查看 477关注 0票数 3

Jetbrains在每一篇关于kotlin的文章中都谈到了异步编程。但我不明白为什么它们被称为异步?据我所知,kotlin协程--这是一个带有预初始化线程池的状态机。我们有一个工作线程池和一个io线程池。对我来说,这只是一个多线程编程。如果我们向协程发送阻塞代码,线程将被阻塞。如果我们使用async方法(来自默认协程库),它会给我们一种异步工作的错觉,但这只是将“job”发送到另一个线程。

如果我们使用带有协程的async io,另一个问题。但这是IO API异步,而不是kotlin协程。与其他语言相比,Java没有很好的io异步api (可能是错误的)。据我所知,.NET已经重建了他们的异步api (作为IOCP)来使用C#任务,并且.NET有专门的线程池来等待所有的应用程序,所以一个线程可以处理许多io操作。但是kotlin协程没有集成到java nio中,当我们从协程调用nio时(不管有没有Dispatcher.IO),我们只是请求一个线程等待来自nio的数据。Java NIO有自己的用于epoll或iocp的线程池,所以使用kotlin协程,当请求Dispatcher.IO给我们一个线程等待来自NIO的结果时,我们就会产生开销,然后,NIO实现创建自己的线程(池)来等待来自套接字的数据。我们现在有两个线程(池)来等待,而不是一个线程(池)。

因此,协程只允许我们以一种简单的方式将作业发送到另一个线程。如果你的api没有用kotlin协程以异步方式实现,你就不能用一个线程同时做多件事。

EN

回答 2

Stack Overflow用户

发布于 2021-09-17 15:52:50

他们谈论异步编程,主要是因为协程(but not limited to)是作为一个库出售的,以使异步编程更容易(主观)。但正如您正确地指出的那样,协程本身并不是异步的。如果你在协程中执行阻塞代码,它将阻塞底层线程。

但要理解的一点是,协程只有在与挂起函数结合使用时才真正有优势,其中线程除了等待结果(回调)之外什么也不做。因此,您可以使用相同的线程再执行10个这样的调用,而不是等待。另一个主要优点是,使用协程编写的异步代码更容易编写和维护。例如,下面是使用回调的异步调用

代码语言:javascript
运行
复制
fun callAPI(){
    getToken{ token ->
        auth(token){ authResult ->
            doSomething(authResult){ finalResult ->
               // use final result
            }
        }
    }
}

这可以简化为使用协程和挂起函数

代码语言:javascript
运行
复制
fun callAPI() = scope.launch(){
    val token = getToken()
    val authResult = auth(token)
    val finalResult = doSomething(authResult)
}

现在,您可以使用协程来启动多个长时间运行的阻塞任务,但您看不到任何优势。因为在这种情况下,协程只不过是线程之上的一个无用的抽象。

票数 1
EN

Stack Overflow用户

发布于 2021-09-17 16:11:41

我会试着从不同的角度来看待这个问题。协程是基于挂起函数的。挂起函数是异步的。

协程是状态机的事实在那里是无关紧要的。状态机可以转换为异步函数链,反之亦然。

您不应该将调度程序视为“线程池”,而应将其视为反应器模式或事件循环。可以,您可以阻止事件循环。然而,这并不意味着事件循环不是异步的,也不意味着您应该这样做。

只有当你不在其中使用挂起函数时,你所说的“异步作业的假象”才是“假象”。由于Kotlin代码的很大一部分是挂起的(flow、Ktor等),实际上,您的大部分代码实际上都是异步的。

Java的NIO具有与Kotlin不同的抽象:回调。可以使用suspendCancellableCoroutine将它们转换为协程

最后一部分大部分是错误的:

协程只允许我们以一种简单的方式将作业发送到另一个线程。如果你的api没有用kotlin协程以异步方式实现,你就不能用一个线程同时做多件事。

单个Dispatcher线程将在多个协程之间进行上下文切换,除非其中一个协程阻塞:不使用任何挂起函数并执行IO或CPU密集型任务。

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

https://stackoverflow.com/questions/69222619

复制
相关文章

相似问题

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