kotlin 协程如何知道到了恢复/挂起的时间?

zynd9foi  于 2022-12-04  发布在  Kotlin
关注(0)|答案(1)|浏览(184)

假设我们有一个作业A和一个作业B(不是Kotlin的Job,只是某种作业),我被告知协程可以挂起,因此A使用的底层线程不会被阻塞,可以用于B,而A挂起。
比如说,A执行某种从服务器下载数据的任务。当A被挂起时(如果它被挂起),A是如何执行这些工作的?它如何知道是时候恢复并再次保持线程了?线程如何处理协程状态并决定运行哪一个?
我猜它在引擎盖下使用了很好的旧等待/通知机制,但是我不清楚,当线程已经用于另一个工作时,示例下载如何发生?

s3fp2yjn

s3fp2yjn1#

当协程被挂起时(如果它被挂起),它如何执行工作?

经过一些研究,我发现,当协程挂起时,它实际上被调度到另一个线程(正如 bylazy 所提到的),在那里它继续执行。

它如何知道是时候恢复并再次保留线程?

以问题中的示例为例,下载将被分派到隐式线程池(* Tenfour 04 * 提到过)的一个单独线程,并将使用continuation对象在前一个线程上继续。
与此同时,前一个线程仍然可以用于其他工作。而Java的Thread有一些不同之处,这解释了为什么协程的性能更高:

  • 线程是一种不同的机制,它与操作系统的本地线程相链接。这就是为什么创建数百/数千个线程是不可能的原因-线程消耗了大量的操作系统内存。协程是一些工作者的用户级抽象,它不使用过多的内存,因为它不链接本地资源,并使用JVM堆的资源。
  • 线程被阻塞,而不是挂起作业并将其分派给另一个线程。
  • 线程在其工作完成之前无法使用。
  • 线程是异步的,而协程是顺序的。根据前面的观点,线程异步地执行某种工作,不能被使用。另一方面,协程是一个用户友好的抽象,在线程上执行,在它被挂起后,下一个协程在同一个线程上执行。(这一点回答了***“线程如何处理协程状态并决定运行哪个协程?***”)

因此,协程可以更好、更有效地利用线程,处理线程调度、资源重用、线程池管理等问题。
我使用的来源:

相关问题