Akka如何实现类似JMM的事先关系?

Eva*_* Y. 10 java multithreading akka

在Akka官方文件中,他们否认:

为了防止演员的可见性和重新排序问题,Akka保证以下两个"之前发生"规则:

actor发送规则:消息发送给一个actor发生在同一个actor接收到该消息之前.actor后续处理规则:一个消息的处理在同一个actor处理下一个消息之前发生.

参阅文档以获取详细信息.

我想知道阿卡如何实现这个目标.我刚刚浏览了源代码(此时最新),我认为在执行之前应该有一个Lock Actor.receive,但我没有找到任何锁(我认为).最后,我发现了一条评论ActorCell.invoke:

//内存一致性由邮箱处理(读取邮箱状态,然后处理邮件,然后写入邮箱状态

是的Mailbox.status,我想这就是我在寻找的东西.我看到他们Unsafe用来访问/更新status字段,但我无法弄清楚如何确保内存可见性.

Rol*_*uhn 14

有两件事需要考虑:传递消息并正确发布actor的内部状态.

前者是通过邮箱的MessageQueue实现实现的,它将使用volatile写入(对于默认的ConcurrentLinkedQueue)或锁(对于普通的LinkedBlockingQueue)来确保安排发布入队项.演员将通过读取相同的易失性字段(在第一种情况下)或采用相同的锁(在第二种情况下)与发送者同步,因此在消息发送之前的所有写入发生在演员处理该消息之前的任何内容之前.

即使通过您找到的邮箱状态在另一个线程上重新安排了actor的内部状态,它也会被安全地存放:处理一批消息(由throughput参数定义)后,邮箱被设置为"未安排"状态,这是一个易失性写(实际上Unsafe.compareAndSetInt(),它具有相同的语义).在actor开始处理消息之前,它使用Unsafe.getIntVolatile与先前写入同步的邮箱状态读取,因此在最后一批消息期间由actor执行的所有写入发生在该批次期间的所有读取之前.

您可以阅读有关此处涉及的操作的语义的更多信息,请记住遵循相同规则的*Volatile方法.sun.misc.UnsafeAtomic*Reference