当执行未来时,我们需要执行上下文。
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.dispatcher
和context.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调度员,请参见此处