当前位置: 首页 > 知识库问答 >
问题:

Akka演员模型。为什么要给Self发消息?

微生嘉
2023-03-14

我是akka的新手,查看现有的代码,看到一个actor从其他人那里得到Message1,然后将Message2发送给self。我知道发送消息优于方法调用是Akka中的关键。但是,我不认为向getSelf()发送消息有什么好处。我看到的代码如下所示:


import java.util.Date;

import akka.actor.AbstractLoggingActor;
import akka.actor.Props;

public class myActor extends AbstractLoggingActor {
    public static class Message1 {
    }

    public static class Message2 {
    }

    private Date date;

    public static Props props(Date date) {
        return Props.create(myActor.class, date);
    }

    @Override
    public Receive createReceive() {
        return receiveBuilder().match(Message1.class, message -> {
            // some state change here, method calls, ...
            getSelf().tell(new Message2(), getSelf());
        }).match(Message2.class, message -> {
            // some code here ...
            this.doSomeLongProcessing();
        }).build();
    }

    private void doSomeLongProcessing() {
        // ... long time is taken here
    }

}

最终,应该有一个对actor类中的方法的阻塞调用(例如,doSomeLongProcessing()),我们将这个调用放在另一个消息处理中,它也不会更好。

在这种情况下,问题是--为什么我们可能需要用akka向自我发送信息?请解释一下,因为我在网上也看到了一些这样的例子。

共有1个答案

穆智刚
2023-03-14

如果没有看到完整的代码和上下文,我想我无法给出一个真正的答案。但是,总的来说,你是对的,在正常情况下,仅仅为了继续正常的处理而给自己发送消息并没有太多的好处。但是我认为这个例子有点做作,因为通常情况下,您不希望在同一个actor中混合阻塞和非阻塞行为。(通常,最佳实践是在一个执行元中处理message1,然后在另一个执行元中处理message2,这样您就可以将第二个执行元放入专用线程池中以阻止执行元。)

然而,在几种情况下,向自己发送消息是有效的。Robert Harvey在上面的评论中提到了其中的两个:当使用计时器向将来的自己发送消息时,以及“管道”模式,即从将来的完成中向自己发送消息时。(这一点很重要,因为您将不再处于完成处理html" target="_blank">程序中的actor上下文中,因此您需要向自己发送一条消息,以便返回上下文。)

我还能想到一些其他的边缘情况,你可能想要发送一个消息给Self。例如,如果您处于阻塞执行元中,向自己发送消息实际上是yield,允许执行元处理其他消息。

如果代码是公开的,我可以更详细地查看一个特定的示例。

 类似资料:
  • 我正在尝试使用Akka和Camel的竞争性事件消费者实现。我使用Akka 2.3.2和Camel 5.8.0。我正在将camel连接到ActiveMQ代理,并使用生产者从另一端生成消息。在以下代码中,EventManager是创建消费者池的主机,Event处理器是消息处理演员。 EventManager.java EventProcessor.java 我看到的问题是,消息似乎被单个参与者使用,而

  • 我正在将现有应用程序从Akka Classic移植到Akka Typed。最初,您可以使用上下文获取对参与者的引用。actorSelection()。resolveOne() 我知道在Akka Type中不再支持这一点,我们应该使用来注册演员以供发现。 但是,我只想将消息发送到本地参与者,即存在于集群中每个节点上的本地单例。我有它的本地路径,但没有对它的直接引用。这是因为它是由Akka管理系统创建

  • 我很想知道调整大小,或者在本例中增加单个节点系统上的actor池中actor的数量是否真的会影响性能。 我有一个带超线程的四核系统。在任何给定的点上,系统可以运行8个线程。假设执行元执行的大多数操作都是CPU绑定的,那么将池中的执行元数量从20个增加到40个会有什么收获呢?

  • 让我们假设一个使用Akka Typed实现的应用程序有一个持久执行元。这个持久执行元作为其操作的一部分创建了瞬态(或非持久)子执行元,每个子执行元都有一个唯一的ID,这些ID是持久状态的一部分。持久执行元还需要一些与其子级通信的方式,但我们不希望持久化子级的,因为它们实际上不是状态的一部分。在恢复时,持久参与者应该基于恢复的状态重新创建它的子级。这听起来并不像是一个很不寻常的用例,我正在试图弄清楚

  • 我正在学习Akka类型的Actor库,并尝试使用。但是它返回一个类型,而不是我最初创建的子参与者的类型- 我所做的解决方法是在创建时将子对象简单地存储在hashmap中。但这不是一个可伸缩的。 我该如何实现这一点?尤其是在分布式场景下?

  • 我正在用Akka打字,但我无法查看官方文件(https://doc.akka.io/docs/akka/current/typed/actors.html#actors),我发现它非常简短,即如何在Actor类型中配置调度程序。 下面是我的代码示例 当我创建ActorSystem时,如何为我的A配置调度程序ctor.immutable?