执行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核心相同。我只知道其中的一些摘要,有人可以解释更多吗?谢谢!
显然您是在演员中使用期货,因为您提到了context.dispatcher和context.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一般使用。但是,如果您要处理期货的冻结操作或长期运行,请使用专用的调度程序来隔离或隔离那些操作,以免影响系统的其余部分。