【问题标题】:Akka group messages into poolsAkka 将消息分组到池中
【发布时间】:2015-06-30 11:39:18
【问题描述】:

我正在尝试专门使用 Java(非 Scala)来理解 AKKA 2.10。我知道并发模式等在 Scala 中更具表现力,但我希望我的示例能够在 Java 中工作。

特别是我有一些产生消息的演员。 “BreadRollActor”生产面包,“BaconActor”生产培根,“SaladActor”生产沙拉。我现在有一个 BurgerAssemblyActor,它接收“消息”,即培根、面包卷、沙拉。我想将 2 条面包卷信息、1 条培根信息和 10 条沙拉信息组合成一个汉堡。作为演员,如何在 Akka Java 中最好地实现这一点。

public class Burger extends UntypedActor {

    private final LoggingAdapter LOG = Logging.getLogger(context().system(), this);

    @Override
    public void onReceive(Object message) throws Exception {
        if(message instanceof Bacon){
            LOG.info("Received Bacon");
            //Possibly add to a queue?
        }
        else if(message instanceof BreadRoll){
            LOG.info("Received BreadRoll");
            //Possibly add to a queue?
        }
        else if(message instanceof Salad){
            LOG.info("Received Salad");
            //Possibly add to a queue?
        }

    }
}

典型的 Java 开发人员的思维方式是将它们添加到队列中,然后运行另一个任务来获取 2 个面包卷、1 个汉堡和 10 个沙拉,制作一个汉堡并将它们放入另一个演员。然而,这意味着我控制了并发,但我假设这不是 akka 的重点? akka 在这里如何帮助我?我正在阅读 FSM 演员等概念,但现在我很清楚如何应用它,因此一些示例代码答案将非常有帮助。

【问题讨论】:

    标签: java java-8 akka


    【解决方案1】:

    我会声明一些包含所需数量的变量;然后,当消息到达时,我会增加它们,然后我会检查是否可以制作汉堡。当条件满足时,记得减去需要的值,这样即使配料以随机顺序到达,actor也能正常工作:

    public class Burger extends UntypedActor {
    
        private static int NEEDED_SALAD = 10;
        private static int NEEDED_BREAD = 2;
        private static int NEEDED_BACON = 1;
    
        private final LoggingAdapter LOG = Logging.getLogger(context().system(), this);
        private int bread, bacon, salad; 
    
        @Override
        public void onReceive(Object message) throws Exception {
            if(message instanceof Bacon){
                bacon ++;
            }
            else if(message instanceof BreadRoll){
                bread ++;
            }
            else if(message instanceof Salad){
                salad ++;
            }
    
            if (salad >= NEEDED_SALAD && bread >= NEEDED_BREAD && bacon >= NEEDED_BACON) {
                salad -= NEEDED_SALAD;
                bread -= NEEDED_BREAD;
                bacon -= NEEDED_BACON;
    
                // and sends message to (or spawns) another actor
            }
        }
    }
    

    【讨论】:

    • Burger 消息包含其他对象 Bacon、BreadRoll、Salad 等的实例,因此我需要保留三个列表。我不确定这对内存的影响。如果我不断收到数百万个培根实例(但没有足够的面包卷),那么大概我用完了那么多内存吧?更好的策略是在另一个 Actor/Thread 中准备一个汉堡,而主接收器可能在一个有界缓冲区类型实体中累积这些对象?
    • 是的,如果它接收到数百万条 Bacon 消息——并且您需要存储所有这些消息——它迟早会在将消息添加到列表时抛出 OutOfMemory 异常。如果您不关心丢失消息,则有界缓冲区可能是一种解决方案;否则,您可以设置一个集群,根据预期的消息量设置大小,以便参与者的每个实例将只收到总消息的一小部分。..
    • @CalmStorm 如果您需要保留对所有培根的引用,即使您可能永远不会得到面包卷,那么再多的线程或任何诡计都无法将您从 OOME 中拯救出来。这与 Akka 甚至编程语言无关,这是一个简单的计算事实。
    猜你喜欢
    • 1970-01-01
    • 2015-12-14
    • 2018-09-29
    • 1970-01-01
    • 2012-07-02
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    • 2014-02-23
    相关资源
    最近更新 更多