私は Akka 2.0 用の Java API を使用していますが、TypedActors を開始および/または停止するために ActorSystem を正しく使用していないことに気が付きました。アプリケーションがシャットダウンしても、Java プロセスは終了しません。デバッグすると、デフォルトのディスパッチャーにはまだ複数の実行中のスレッドがあり、スケジューラーも実行中であることがわかります。以下の例で明らかに間違っていることはありますか?
Config akkaConf = ConfigFactory.load();
ActorSystem actorSystem = ActorSystem.create("myApp", akkaConf);
TypedProps<Actor1Impl> actor1TypedProps = new TypedProps<Actor1Impl>(Actor1Interface.class, new Creator<Actor1Impl>(
public Actor1Impl create() {
return new Actor1Impl(nonDefault, constructor, scalaIsSo, muchMoreElegant);
}
);
Actor1Interface a1 = TypedActor.get(actorSystem).typedActorOf(actor1TypedProps, "anA1Actor");
読者には知られていませんが (簡潔にするために)、Actor1Impl クラスは TypedActor.PreStart と .PostStop を実装しています。PreStart では、Runnable タスクを定期的に実行するようにスケジュールします。これで Scheduler をアクティブに保つことができたのではないかと思いましたが、返された Cancellable も保存しました。これは、PostStop ブロックでキャンセルする必要があると思います。これは、スケジューラ スレッドを終了するのに役立ちませんでした。それはともかく、話を戻して…
他にも多数のアクター タイプがあり、それぞれが非標準コンストラクターを持ちます。これらのいくつかは、上記の Actor1Impl と同様に、定期的な Runnable をスケジューラに登録します。さらに、次のように、アクターがコールバックに登録するために、コンストラクターの引数として他のアクタを必要とするものもあります。
public Actor2Impl(Actor1Interface a1) {
a1.registerCallback(TypedActor.<Actor2Interface>self());
}
アプリがその有用性を失ったと判断された後、次のことが実行されます。
TypedActor.get(actorSystem).stop(a1);
TypedActor.get(actorSystem).stop(a2);
...
TypedActor.get(actorSystem).stop(aN);
actorSystem.shutdown();
Javaプロセスが終了しないようにする、あからさまに間違っていることはありますか? 具体的には、スケジューラーとデフォルトのディスパッチャーがシャットダウンする原因となるものはありますか?