ForkJoinPool和Kotlin协同程序

时间:2019-03-12 21:46:39

标签: kotlin forkjoinpool kotlin-coroutines

据我了解,默认情况下,如果您通过launchasync启动Kotlin协程,它将在CommonPool中启动(或者如果您使用GlobalScope) 。 CommonPoolForkJoinPool,默认情况下处于非异步模式,因此它以LIFO顺序执行任务。对于异步Web服务器应用程序来说,这似乎是一个非常糟糕的选择,因为我们希望公平调度:我们不希望先打到我们的Web服务器上的那个可怜的傻瓜等待以后的所有呼叫。

但是,Kotlin协程在这里增加了额外的麻烦,因为Kotlin标准库中有一些代码将安排执行那些协程(据我所知,标准的asyc select / epoll循环有些变化)。那么也许LIFO事情不是要担心的?

我当然可以进行一些实验和/或调试器中的代码,以了解其工作原理,但是我怀疑其他人也有同样的问题,我敢打赌有人“才知道”答案...

2 个答案:

答案 0 :(得分:0)

这不必担心,因为ForkJoinPool并不是真正的LIFO。

也就是说,它是池中单个线程的LIFO,但这就是“偷工作的一部分”而变得有趣的地方。每个线程的任务队列是双链接的。因此,一个线程的LIFO是什么,而另一个空闲的线程的FIFO是什么。

通常,ForkJoinPool是处理小型任务的理想解决方案,如果明智地使用了挂起函数,通常协程就很小。

此外,您可以在文档中了解有关asyncMode的更多信息,因为它不是“异步”的:https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html

  

asyncMode-如果为true,则建立本地先进先出调度   模式,用于从未加入的分叉任务。此模式可能更多   在以下应用程序中比默认的基于本地堆栈的默认模式合适   哪些工作线程仅处理事件样式的异步任务。对于   默认值,请使用false。

答案 1 :(得分:0)

在Kotlin上每个discussion讨论CommonPool不再是默认值,现在它们默认为“大多数情况下”的调度程序。链接的讨论中有详细信息。