Akka 循环路由器不考虑实例数

时间:2021-03-23 17:53:09

标签: java-8 akka actor

我有以下代码:

class ARouter {
    public static ActorRef getRouter(actorContext, param1, param2, routerName) {
        ActorRef router;

        try {
            RoundRobinPool roundRobinPool = new RoundRobinPool(1);
            Props props = Props.create(MyActor.class, param1, param2, param3);
            router = actorContext.actorOf(roundRobinPool.props(props), routerName);
        } catch (Exception e) {
            
            router = null;
        }

        return router;
    }
}

在我的代码中我这样做

ActorRef router = ARouter.getRouter(actorContext, param1, param2, routerName);
anObject.getAListOfItems().forEach(listItem -> router.tell(listItem, getSelf()));

我希望看到一个线程,因为虽然我将消息发送到路由器以将它们分派给参与者,但路由器创建时只有一个路由(如果我理解正确的话)。

我尝试了不同数量的实例,但我总是得到 8 个线程。唯一有效(当然也“崩溃”)的想法是设置 new RoundRobinPool(0) 有效并且应用程序抗议没有演员可用。

没有使用自定义配置文件。路由器的逻辑有什么我不明白的地方吗?

1 个答案:

答案 0 :(得分:0)

您在问什么并不完全清楚(您的代码在任何地方都没有提到线程),但是在 Akka 中,当角色有要处理的消息时,调度程序会安排角色的消息处理在线程上运行。标准实现利用线程池(在 2.6 中,默认池的大小等于内核数(将超线程视为一个内核),默认情况下 2.5 使用更大的池来防止无意中阻塞饥饿系统组件): Actor 在该实现中的消息处理可以发生在池中的任何线程中。

因此,例如,如果您的 actor 正在记录他们正在运行的线程,您可能会看到该 actor 正在多个线程上运行。这通常是可取的:actor 的一次一条消息处理模型仍然确保安全,并且不会被固定到特定线程,这意味着池中有 n 个线程,任意组合n 个参与者可以同时处理。

有替代的调度器实现可以将一个actor固定到一个线程:如果actor A和B都固定到线程T,那么如果A正在处理一条消息,B就不能处理一条消息。在某些情况下,这会减少上下文切换开销并以一定的延迟成本提高吞吐量。

一般来说,actor 不应该关心它在哪个特定线程上运行。

相关问题