就异步编程而言,这可能是一个非常基本的问题,但我尝试阅读有关该内容的信息,但找不到相同的任何资源。
假设:通常,关于异步编程,我的想法是
当我们开始阻塞操作(网络调用,从数据库/文件读取)时,我们可以将其委派给内核线程,这将使我们的应用程序线程可用于其他作业。内核线程等待作业完成,并在作业完成时向应用程序线程提供回调。
协程:最近几天,我一直在阅读有关Kotlin协程的信息。我认为明智的协程在语言上是不可知的。我一直得到的问题是:
suspension
和continuation
对于协同例程如何发生。协程不是线程(操作系统给它分配了处理器的一部分),而是tasks
,它们将在要执行的线程上进行调度。
谁一直在寻找正在执行的程序,并说此协程已达到挂起点,应将其从线程中删除。应该在线程上安排需要从continuation
恢复的另一个协程。至于我所读过的Java Fibers
,将由Fiber Scheduler
完成,在Kotlin中是否类似?
谢谢您的帮助。
答案 0 :(得分:2)
协程暂停是完全明确且一流的。当您调用suspendCoroutine()
或suspendCancellableCoroutine()
,并传入一个接收连续性作为参数的块时,就会发生这种情况。
该块可以对延续对象执行任何所需的操作,并且当某人在某个地方调用continuation.resume(resultValue()
时,它将恢复。它继续在其上运行的线程最初是调用resume()
的线程,但是resume
内部的逻辑立即委派给负责的Dispatcher,后者通常将恢复提交给另一个线程或线程池。
Dispatcher逻辑仍然是一流的,您可以编写自己的调度程序。但是,几乎不需要这样做,因为只有少数几种有意义的方法可以做到这一点,而Kotlin已经支持了它们。
您还可以查看concrete example in code,它演示了suspendCoroutine
和coroutine.resume()
的裸露用法,而没有Dispatcher添加的图层。
顺便说一句,您永远不要将阻塞操作委托给“内核线程”以使它们成为非阻塞的。异步操作不会阻塞任何线程。在较低的级别上,例如有 selector 的机制,该机制在IO操作完成时接收事件。它的工作原理类似于GUI线程中的事件循环。