"UntypedActor" 在 Akka (Java) 教程中已被弃用的解决方案

15

原始代码

Akka教程包含以下代码:http://doc.akka.io/docs/akka/2.0.2/intro/getting-started-first-java.html

public void calculate (final int nrOfWorkers, final int nrOfElements, final int nrOfMessages){
    ActorSystem system = ActorSystem.create("PiSystem");
    final ActorRef listener = system.actorOf(Props.create(Listener.class), "listener");
    ActorRef master = system.actorOf(new Props(new UntypedActorFactory() {
            public UntypedActor create() {
                return new Master(nrOfWorkers, nrOfMessages, nrOfElements, listener);
            }
    }), "master");
    master.tell(new Calculate(), ActorRef.noSender());
}

其中,UntypedActorFactory已被弃用。

我的修改

因此,我尝试使用Props.create,例如:

ActorRef master = system.actorOf( Props.create(
            new Creator<Master>(){
                public Master create(){
                    return new Master(nrOfWorkers, nrOfMessages, nrOfElements, listener);
            }
    }), "master");

出现异常,提示无法使用非静态的本地创建器来创建演员; 让它成为静态或顶级。

因此我开始编写一个静态类,其中包含需要传递的参数。

static class LocalCreator implements Creator<Master>{
    public Master create(){
        return new Master(nrOfWorkers, nrOfMessages, nrOfElements, listener);
    }
}

问题

如何优雅地将nrOfWorkers等参数传递到create()函数中?


你需要学习一下嵌套类。顺便说一句,已经有无数个版本的这个问题在SO上被问过了。 - Andrew
@Adnrew,那么您将失去用于创建的参数。您熟悉Akka吗?已弃用的UntypedActor允许使用非静态类的实例。但是新版本不允许。也许有一种类的版本允许非静态类。这就是为什么会发布这个Akka问题的原因。 - Splash
我已经使用2.3.11版本的Java创建了一个更新的教程。请尝试:https://github.com/Shaulian/Actors-Pi-Calc-using-2.3.11-akka-java-version。 - Shaulian
1个回答

22

如果你阅读Akka文档(Java版本),它列出了两种构建带有构造函数参数的Actor的方式。第一种方法如下(使用您的示例类):

ActorSystem system = ActorSystem.create("PiSystem");
final ActorRef listener = system.actorOf(Props.create(Listener.class), "listener");
ActorRef master = system.actorOf(Props.create(Master.class, nrOfWorkers, nrOfMessages, nrOfElements, listener), "master");
master.tell(new Calculate(), ActorRef.noSender());

或者如果你不想这么做,你可以使用一个名为Creator的东西,像这样:

public class MasterCreator implements Creator<Master>{
  private int nrOfWorkers, nrOfMessages, nrOfElements;
  private ActorRef listener;
  public MasterCreator(int nrOfWorkers, int nrOfMessages, int nrOfElements, ActorRef listener){
    this.listener = listener;
    this.nrOfElements = nrOfElements;
    this.nrOfMessages = nrOfMessages;
    this.nrOfWorkers = nrOfWorkers;
  }

  public Master create(){
    return new Master(nrOfWorkers, nrOfMessages, nrOfElements, listener);
  }
}

然后像这样使用它:

  ActorSystem system = ActorSystem.create("PiSystem");
  final ActorRef listener = system.actorOf(Props.create(Listener.class), "listener");
  ActorRef master = system.actorOf(Props.create(new MasterCreator(nrOfWorkers, nrOfMessages, nrOfElements, listener)), "master");
  master.tell(new Calculate(), ActorRef.noSender());

谢谢,你的第一个解决方案绝对有效。但是你的第二个看起来和我失败的代码一模一样。它给了我一个异常java.lang.IllegalArgumentException: cannot use non-static local Creator to create actors; make it static or top-level。 - Splash
@Splash,干得好。我更新了我的解决方案,不再包括匿名类方法,因为似乎不被允许。 - cmbaxter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接