Akka onReceive方法是否同时执行?

时间:2012-07-26 15:50:58

标签: synchronization actor akka

以下是我的情景:

我有一个主演员,它接收来自多个子演员的消息。这些消息包含要聚合的数据。在这种聚合逻辑中,如果我使用共享数据结构来收集聚合,我是否需要处理同步问题?

else if(arg0 instanceof ReducedMsg){

                           ReducedMsg reduced = (ReducedMsg)arg0;
        counter.decrementAndGet();

        synchronized(finalResult){

            finalResult.add((KeyValue<K, V>) reduced.getReduced());

            if(counter.get() == 0){
                                    if(checkAndReduce(finalResult)){

                    finalResult.clear();
                }
                else{
                    stop();
                    latch.countDown();
                }

            }

        }



    }

因为你可以看到我有一个finalResult,每个消息都会聚合到这个消息,并且在处理逻辑之后,集合也需要被清除。

实际上我想要实现的是递归(关联)缩减mapreduce。所以我需要保持我假设的同步块?或者Akka是否一次执行onReceive一个线程?

此逻辑可在小数据集上生成准确且可预测的结果。我的问题是当我的输入数据集有点大时,代码挂起。我想确定这是因为我的同步块的上下文切换,所以我可能会遇到不同的设计。

1 个答案:

答案 0 :(得分:18)

onReceive() 从不同时调用。这是Akka给您的最基本保证。

这意味着,如果您的counter变量是演员中的某个字段,而其他任何代码都无法直接访问该字段,则可以安全地使用普通int / long代替AtomicInteger / AtomicLong。此外,finalResult上的同步也不是必需的,假设它是一个封装并隐藏在actor中的字段。

最后CountDownLatch的使用是可疑的。在Akka应用程序中,您不应使用任何同步原语。参与者本质上是单线程的,所有通信(包括唤醒和传递数据)都应该通过消息传递来实现。

文档中解释了这一点:http://doc.akka.io/docs/akka/2.0.2/general/jmm.html#Actors_and_the_Java_Memory_Model