演员:如何有效地处理读取数据

时间:2010-12-04 18:52:52

标签: scala actor akka

假设我有一个拥有单个字段的actor。每100封给一个演员的消息中有99个读取该值,而第100个消息更新该值。在这种情况下,我想并行处理读取。换句话说,如何使用Actors实现读/写锁的性能?这与Scala标准演员或Akka一样实用吗?或者我错过了演员的观点:)

更新:修复了令人困惑的语言,抱歉

4 个答案:

答案 0 :(得分:6)

你很可能忽略了演员的观点。我假设您想要一个发送查询的actor,然后它会发回一个响应。有很多机器涉及向演员发送消息,处理消息并发送回复。响应消息的实际生成将作为任务创建并提交给线程池。在消息队列和线程池之间有多个需要锁定或最佳CAS操作的位置。通常关键是演员将在基于该消息的单独线程中完成一些工作。

如果您只想阅读并且很少写数据(例如递增计数器或访问地图中的值),那么使用java.util.concurrent中的相应类会更好。

答案 1 :(得分:6)

[免责声明:我是Akka的PO]

我建议使用代理,读取可以在任何时候完成,但一次只能写一次。

http://doc.akkasource.org/agents-scala

编辑:http://doc.akka.io/docs/akka/2.1.0/scala/agents.html(试试此链接)

答案 2 :(得分:3)

我认为你的意思是所有消息都是不可变的,并且几乎所有消息都不会改变actor的状态。在这种情况下,演员可能不是最好的设计选择。 Actors允许您管理任何可变状态,就像处理单线程代码一样。

实际上,每个actor都有一个邮箱,邮件发送到该邮箱,然后一次处理一个邮箱。在您的场景中,这将非常浪费。如建议的那样,使用java.util.concurrent中的内容将是最有效的。

答案 3 :(得分:2)

演员用于连续处理消息。这使得它们易于推理:您一次只能获得一条消息,因此可以修改actor中的任何变量(只要它们不被其他任何人变异),而无需考虑并发性。这是最有效的方法吗?绝对不!但效率低下的代码几乎总是优于高效的代码

你要求的恰恰相反:你想要明确地考虑并发性(“我知道99%的访问将是读取,因此可以并行发生!”)以获得处理速度。在这种情况下,您可能希望使用java.util.concurrent.locks.ReentrantReadWriteLock直接控制对可变变量的访问(如果java.util.concurrent.atomic._中找到的访问类型不适合您)。请记住,你现在承担了正确锁定的责任,并且要小心谨慎。