2010-12-04 59 views
5

假设我有一个演员只有一个字段。每100条消息中有99条读取值,第100条更新值。在这种情况下,我想并行处理读取。换句话说,我怎样才能实现使用Actor的读/写锁的性能?对于Scala标准演员或Akka,这是否实用?还是我缺少的演员:)演员:如何有效地处理读取主要数据

更新的点:固定混乱的语言,对不起

+1

是不是所有给演员的消息都是只读的(不可变的)?参与者收到消息并根据消息的内容进行一些处理。如果需要,它会将消息发送给另一个参与者作为处理的一部分。 – 2010-12-04 19:04:47

+0

是的,这些消息是不可变的。想象一下作为一个参与者的计数器/增量器的常见例子:我想知道如果读取当前值对于其他读取操作可以是非阻塞的。 – 2010-12-04 19:11:08

回答

6

你很可能是失踪者的地步。我假设你想要一个你发送查询的演员,然后它发回一个响应。有相当多的机制涉及向演员发送消息,处理消息并发回响应。实际生成的响应消息将作为任务创建并提交给线程池。在消息队列和线程池之间有多个需要锁定或CAS操作的地方。通常重点是演员会根据该消息在单独的线索中完成一些工作。

如果您只想读取并很少写入数据(例如递增计数器或访问映射中的值),那么使用java.util.concurrent中的适当类会更好。

3

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

实际上,每个参与者都有一个邮箱,邮件发送到该邮箱,然后一次处理一个邮箱。在你的情况下,这将是相当浪费。正如所建议的那样,使用java.util.concurrent中的内容将是最有效的。

2

演员的目的是串行处理的消息。这使得他们很容易理解:一次只能得到一条消息,因此可以在不考虑并发性的情况下修改参与者中的任何变量(只要他们没有被其他人突变)。这是最有效的方法吗?绝对不!但效率低下的代码能够正常工作几乎总是优于高效代码被破坏。为了获得处理速度,你所要求的是完全相反的:你想明确地考虑并发性(“我知道99%的访问将是读取,因此可以并行发生!”),以获得处理速度。在这种情况下,您可能希望使用java.util.concurrent.locks.ReentrantReadWriteLock直接控制对可变变量的访问(如果在java.util.concurrent.atomic._中找到的访问类型对您不适用)。请记住,您现在已经承担了正确锁定的责任,并且要小心。

相关问题