akka getContext(). become()热交换未接收消息

kb5ga3dv  于 2022-11-23  发布在  其他
关注(0)|答案(1)|浏览(116)

在akka中有代码并使用become()需要了解为什么它只接收第一个msg,然后忽略...

package ping_pong;
import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;

public class PingPongActor extends AbstractActor {

    public static void main(String[] args) throws Exception {
        ActorSystem _system = ActorSystem.create("PingPongActorApp");
        ActorRef masterpp = _system.actorOf(Props.create(PingPongActor.class),                 "pp");

        masterpp.tell(PING, masterpp);
        System.out.println("after first msg");
        masterpp.tell(PING, masterpp);
        masterpp.tell(PING, masterpp);
        masterpp.tell(PING, masterpp);
        masterpp.tell(PING, masterpp);
        masterpp.tell(PING, masterpp);
        System.out.println("last msg");

    }

    static String PING = "PING";
    static String PONG = "PONG";
    int count = 0;

    @Override
    public Receive createReceive() {
        return receiveBuilder().match(String.class, ua -> {
            if (ua.matches(PING)) {
                System.out.println("PING" + count);
                count += 1;
                Thread.sleep(100);
                if (count <= 10) {
                    getSelf().tell(PONG, getSelf());
                }

                getContext().become(receiveBuilder().match(String.class, ua1 -> {
                    if (ua1.matches(PONG)) {
                        System.out.println("PONG" + count);
                        count += 1;
                        Thread.sleep(100);
                        getContext().unbecome();
                    }
                }).build());

                if (count > 10) {
                    System.out.println("DONE" + count);
                    getContext().stop(getSelf());
                }
            }
        }
        ).build();
    }
}

它给出的结果是:
21:36:34.098 [PingPongActorApp-akka.actor.default-dispatcher-4]信息akka.event.slf4j.Slf4jLogger -Slf 4jLogger在第一条消息和最后一条消息PING 0 PONG 1之后启动
问题是为什么它忽略其他PING或PONG消息...?

nmpmafwu

nmpmafwu1#

当你getContext().become时,你是在替换那个演员的 * 整个 * Receive,所以

getContext().become(receiveBuilder().match(String.class, ua1 -> {
    if (ua1.matches(PONG)) {
        System.out.println("PONG" + count);
        count += 1;
        Thread.sleep(100);
        getContext().unbecome();
    }
}).build());

您正在安装Receive,它只会回应符合PONG的邮件。
顺便说一句:Thread.sleep基本上是您在actor中所能做的最糟糕的事情,因为它阻止了actor执行任何操作,并且还消耗了一个调度程序线程。在100米利斯内为您自己安排一个消息将是一个更好的主意,这将触发unbecome

相关问题