为Akka应用程序中的Future选择哪个ExecutionContext?

3 scala akka

执行Future时,我们需要一个执行上下文。

Afaik,我们可以使用以下解决方案:

1。

import scala.concurrent.ExecutionContext.Implicits.global
Run Code Online (Sandbox Code Playgroud)

2。

import context.dispatcher
Run Code Online (Sandbox Code Playgroud)

要么

implicit val ec = context.system.dispatcher
Run Code Online (Sandbox Code Playgroud)

3。

implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))
Run Code Online (Sandbox Code Playgroud)

我的问题是:它们之间有什么区别?建议的方式是什么?

例如,解决方案2将重用actor的调度程序,而解决方案1将使用单独的固定池,线程号与cpu核心相同。我只知道其中的一些摘要,有人可以解释更多吗?谢谢!

Jef*_*ung 6

显然您是在演员中使用期货,因为您提到了context.dispatchercontext.system.dispatcher。请注意,这两个选项不一定相同(但通常是相同的):

  • context.system.dispatcher默认的调度程序
  • context.dispatcher 是特定角色的调度程序,与默认调度程序相同,除非您以编程方式或通过配置为角色设置了自定义调度程序。

关于ExecutionContext在actor中与Future一起使用,文档建议以下内容:

如果actor调用的Future调用的性质与该actor的活动匹配或兼容(例如,所有CPU绑定且无延迟要求),则可能最容易通过导入来重用调度程序来运行Future context.dispatcher

但是,如果Future包装了一个阻塞操作,则使用context.dispatcher(如上所述,它通常是默认的调度程序)使用可能会导致共享同一调度程序的其他参与者饿死线程。在这种情况下,请使用专用的调度程序,您的actor中将需要这样的调度程序

implicit val executionContext: ExecutionContext =
  context.system.dispatchers.lookup("my-blocking-dispatcher")
Run Code Online (Sandbox Code Playgroud)

my-blocking-dispatcher将在中定义application.conf。例如:

my-blocking-dispatcher {
  type = Dispatcher
  executor = "thread-pool-executor"
  thread-pool-executor {
    fixed-pool-size = 10
  }
  throughput = 1
}
Run Code Online (Sandbox Code Playgroud)

另请注意,在配置中定义自定义调度程序并让actor系统实例化它是在Akka中设置线程池的首选方法。也就是说,使用上述方法而不是使用

implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))
Run Code Online (Sandbox Code Playgroud)

简而言之,在参与者中使用Future时,请考虑context.dispatcher一般使用。但是,如果您要处理期货的冻结操作或长期运行,请使用专用的调度程序来隔离或隔离那些操作,以免影响系统的其余部分。