假设我需要运行一些并发任务。
我可以将每个任务包装在 a 中Future
并等待它们完成。或者,我可以为每个任务创建一个Actor
。每个都Actor
将执行其任务(例如,在接收到“开始”消息时)并将结果发回。
我想知道何时应该使用前者(with Future
s)和后者(with Actor
s)方法,以及为什么认为该Future
方法更适合上述情况。
假设我需要运行一些并发任务。
我可以将每个任务包装在 a 中Future
并等待它们完成。或者,我可以为每个任务创建一个Actor
。每个都Actor
将执行其任务(例如,在接收到“开始”消息时)并将结果发回。
我想知道何时应该使用前者(with Future
s)和后者(with Actor
s)方法,以及为什么认为该Future
方法更适合上述情况。
因为它在语法上更简单。
val tasks: Seq[() => T] = ???
val futures = tasks map {
t => future { t() }
}
val results: Future[Seq[T]] = Future.sequence(futures)
results
未来您可以等待使用,Await.result
或者您可以进一步映射它/在理解中使用它或在其上安装回调。
将其与实例化所有参与者、向它们发送消息、编码它们的receive
块、接收它们的响应并关闭它们相比——这通常需要更多的样板文件。
作为一般规则,使用适合您的应用程序的最简单的并发模型,而不是最强大的。从最简单到最复杂的顺序是顺序编程->并行集合->futures->无状态actors->有状态actors->具有软件事务内存的线程->具有显式锁定的线程->具有无锁算法的线程。选择此列表中解决您问题的第一个。你走的越远,复杂性和风险就越大,所以你最好用简单性来换取概念上的力量。
我倾向于认为当你有交互线程时演员很有用。在您的情况下,似乎所有工作都是独立的;我会使用期货。