每当我需要同时运行两个线程时,我就会使用actor。我没有明确地使用线程。
有人告诉我,演员很重,使用它们并不总是一个好主意。使用演员以及何时不使用演员的正确场景是什么?
我的一些演员只是有一个循环但没有反应。这是一个好习惯吗?
[编辑]
答案 0 :(得分:10)
Actors提供了一个带有消息传递计算模型的分布式异步算法,并且最适合适合该模型的任务。
Scala的演员可以共享内存,使其足够依赖于内存共享的算法,但不是特别如此,因为你放弃了演员的主要优势。另一方面,也没有特别的缺点。
有关详细信息,请参阅维基百科上的Distributed Computing。
有两类主要任务并不是特别合适:
严重依赖同步的任务
这与锁定无关,或者在开始其他操作之前等待某些事情。同步系统的主要特征是严重依赖于任务的时间顺序。
例如,如果您需要知道哪个任务首先完成,那么演员缺乏对邮件排序的保证,这使得它们不合适。
< / LI>这是在不同数据块上执行相同计算的情况,它们之间没有依赖关系。
map-reduce算法的“map”部分符合这种情况。
虽然actor可以做到这一点,但是使用fork / join设置可以完成同样的事情而且开销更少。 Scala 2.9将具有针对此类任务的并行集合。
答案 1 :(得分:3)
嗯,很容易假设只是因为两段代码正在运行的是不同的线程,如下所示:
new Thread(work1).start()
new Thread(work2).start()
他们必须同时运行。当然,情况不一定如此,并且主要由OS决定。因此,有可能通过将一段连续工作拆分成大量并行子计算,您所做的只是创建对象创建和上下文切换的开销。
然而,位于Scala的actor系统下的 ForkJoin 框架应该适当调整其内部线程池的大小。这消除了不必要的上下文切换开销,只留下任何(可能不必要的)对象/创建的开销
答案 2 :(得分:0)
根据问题的编辑,似乎你使用Actors来运行单个操作,这不是actor模型的目的。 Actor-Model的发明者清楚地说"One actor is no actor",这意味着为了使用actor模型,我们应该将它作为一个整体系统使用。
因此,Actor应该在循环中运行代码,而不是运行循环本身。然后,actor应该(异步地)获取消息并根据消息类型和参数进行操作。 把它想象成一个让演员做事的指令队列。
答案 3 :(得分:0)
@ Jus12 - 您描述的方案最好使用Akka IO来处理。其文档中提供的I / O示例简单,小巧且易于理解。由Akka IO提供的一个演员负责低级I / O;您提供了第二个actor来监视和恢复连接,第三个actor由您提供来执行“真正的”I / O.
对这些演员的测试也非常简单。使用AkkaTestKit并看到每个actor按预期响应一组非常简单的输入。
在许多情况下,使用Akka库的开销远远超过了自己的应用程序的维护费用。