在Scala中,期货何时比Actors更合适(反之亦然)?

Mic*_*ael 8 concurrency scala future actor

假设我需要运行一些并发任务.

我可以将每个任务包装Future在一起并等待它们完成.或者,我可以Actor为每个任务创建一个.每个人都Actor将执行其任务(例如,在接收到"开始"消息时)并将结果发回.

我想知道何时应该使用前者(使用Futures)和后者(使用Actors)方法,以及为什么这种Future方法对于上述情况更好.

axe*_*l22 7

因为它在语法上更简单.

val tasks: Seq[() => T] = ???
val futures = tasks map {
  t => future { t() }
}
val results: Future[Seq[T]] = Future.sequence(futures)
Run Code Online (Sandbox Code Playgroud)

results未来,你可以再等上使用Await.result,也可以进一步将其映射/用它换理解或安装回调就可以了.

相比之下,实例化所有演员,向他们发送消息,编码他们的receive块,接收他们的响应并关闭它们 - 这通常需要更多的样板.

  • 不同之处还在于底层实现,但Actor模型通常是一个更强大和更具表现力的编程模型 - 您可以使用actor创建类似于Futures API的API.使用期货来实施演员会更加繁琐. (2认同)
  • 期货API通常通过创建fork/join任务并将其推送到fork/join池来工作,然后fork/join池将任务分配给其中一个工作线程.它有时通过批量执行从单个未来执行的计划执行的任务来优化(上次我检查).actor实现还依赖于一个线程池并处理一个任务中存储在一个actor邮箱中的消息,但是我对其内部的知识不足以告诉你更多. (2认同)

Dav*_*ith 6

作为一般规则,使用适合您的应用程序的最简单的并发模型,而不是最强大的.从最简单到最复杂的排序将是顺序编程 - >并行集合 - >期货 - >无状态演员 - >有状态演员 - >具有软件事务存储器的线程 - >具有显式锁定的线程 - >具有无锁算法的线程.选择此列表中的第一个解决问题的方法.你去的列表越往下,复杂性和风险就越大,所以你最好简单地交易概念性权力.

  • 我将把 future 视为阻塞队列的一个特殊情况,并将你对 future 的考虑应用于所有阻塞队列。无论如何,我喜欢这个讨论,但恐怕它在这里已经成为题外话了。如果您想在其他地方继续,请告诉我(电子邮件地址在我的个人资料中)。 (2认同)