在Akka应用程序中选择哪个ExecutionContext为将来选择



当执行未来时,我们需要执行上下文。

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

1。

import scala.concurrent.ExecutionContext.Implicits.global

2。

import context.dispatcher

implicit val ec = context.system.dispatcher

3。

implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))

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

例如。Solution2将重复使用Actor的调度程序,而Solution1将使用单独的固定池,线程号与CPU Core相同。我只知道一些差异的片段,有人可以解释更多吗?谢谢!

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

  • context.system.dispatcher是默认调度程序。
  • context.dispatcher是特定演员的调度程序,除非您通过编程或通过配置为演员设置自定义调度程序,否则它与默认调度器相同。

至于ExecutionContext在演员内部与未来一起使用,该文档建议以下内容:

如果演员匹配引用的未来电话的性质或与该演员的活动兼容(例如,所有CPU绑定且无延迟要求(,那么最容易重用调度员来通过导入运行期货context.dispatcher

但是,如果未来包裹了阻止操作,则使用context.dispatcher(如前所述,通常是默认调度程序(可能会导致其他参与者共享相同的调度员来饿死线程。在这种情况下,请使用专用调度员,在您的演员中想要这样的东西:

implicit val executionContext: ExecutionContext =
  context.system.dispatchers.lookup("my-blocking-dispatcher")

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

my-blocking-dispatcher {
  type = Dispatcher
  executor = "thread-pool-executor"
  thread-pool-executor {
    fixed-pool-size = 10
  }
  throughput = 1
}

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

implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))

简而言之,在参与者内使用期货时,请考虑使用context.dispatcher。但是,如果您正在处理期货的阻止或长期运营,请使用专用调度员来隔离或隔离这些操作,从而不影响系统的其余部分。

Future本身是功能的描述。要执行,它需要从执行上下文中获取的Thread

您提到context.dispatcher,比您使用akka。每个演员执行时,也通过特定执行上下文执行。当您使用context.dispatcher运行Future时,您可以在当前参与者使用的同一线程池中运行此Future。换句话说,您共享可用的线程数量(有限!(用于其他功能。根据您的期货执行时间的时间,如果所有线程都未完成期货占据,则演员可以开始等待可用线程。

在Akka中,您可以在配置文件中定义线程池(dispatchers(。并相应地部署演员。对于期货,您可以使用特定线程池开始使用任何一个演员的调度员(在这种情况下,我建议不要使用全球,而是为期货定义特定的Akka调度员(。取决于您的应用程序(两种情况都可以(

关于Akka调度员,请参见此处

最新更新