我有以下代码:
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)
,它可以工作,但应用程序抗议说没有可用的参与者。
不使用自定义配置文件。路由器的逻辑中有没有我不明白的地方?
发布于 2021-03-24 18:03:16
不完全清楚您在问什么(您的代码没有引用线程),但是在Akka中,当参与者有消息要处理时,调度程序将参与者的消息处理安排在线程上运行。标准实现利用了线程池(在2.6中,默认池的大小等于核心数(将超线程算作核心),2.5默认使用更大的池,以防止无意中阻塞饥饿系统组件):该实现中参与者的消息处理可以在池中的任何线程中发生。
因此,例如,如果您的参与者正在记录它们在哪个线程上运行,您可能会看到该参与者正在多个线程上运行。这通常是可取的:参与者的一次一条消息的处理模型仍然确保了安全性,而不是依次固定到特定的线程,这意味着池中有n个线程,可以同时处理n个参与者的任何组合。
还有一些替代的分派器实现可以将参与者固定到线程:如果参与者A和B都固定在线程T上,那么如果A正在处理消息,那么B就不能处理消息。在某些情况下,这减少了上下文切换开销,并以延迟为代价提高了吞吐量。
一般来说,参与者不应该关心它在哪个特定的线程上运行。
https://stackoverflow.com/questions/66768632
复制相似问题