- 一个Actor在actorOf()函数被调用后开始建立,Actor实例创建后,会回调preStart()方法。在这个方法里,我们可以进行x些资源的初始化工作。
- 在Actor的工作过程中,可能会出现一些异常,这种情况下,Actor会需要重启。当Actor被重启时,会回调preRestart()方法(在老的实例上),接着系统会创建一个新的Actor对象实例(虽然是新的实例,但它们都表示同一个Actor)。当新的Actor实例创建后,会回调postRestart()方法,表示启动完成,同时新的实例将会代替旧的实例。
- 停止一个Actor也有很多方式,你可以调用stop()方法或者给Actor发送一个PosionPill(毒药丸)。Actor停止时,postStop()方法会被调用,同时这个Actor的监视者会收到一个Terminated消息。
实例
public class MyWorker extends UntypedActor {
private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);
public static enum Msg {
WORKING, DONE, CLOSE;
}
@Override
public void preStart() throws Exception {
System.out.println("MyWorker is starting");
}
@Override
public void postStop() throws Exception {
System.out.println("MyWorking is stoping");
}
@Override
public void onReceive(Object msg) throws Exception {
if (msg == Msg.WORKING) {
System.out.println("I am working");
}
if (msg == Msg.DONE) {
System.out.println("Stop working");
}
if (msg == Msg.CLOSE) {
System.out.println("I will shutdow");
getSender().tell(Msg.CLOSE, getSelf());
getContext().stop(getSelf());
} else {
unhandled(msg);
}
}
}
/**
* @author bzb
* @Description: 监视者,如同劳动监工一样,一旦被监视者因为停止工作,则监视者就会收到一条消息
* @date 2018/9/14 14:27
*/
public class WatchActor extends UntypedActor {
private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);
public WatchActor(ActorRef actorRef) {
getContext().watch(actorRef);
}
@Override
public void onReceive(Object msg) throws Exception {
if (msg instanceof Terminated) {
System.out.println(String.format("%s has terminated, shutting down system", ((Terminated) msg).getActor().path()));
getContext().system().shutdown();
} else {
unhandled(msg);
}
}
}
public class DeadMain {
public static void main(String[] args) {
ActorSystem system = ActorSystem.create("deadwatch", ConfigFactory.load("samplehello.conf"));
ActorRef worker = system.actorOf(Props.create(MyWorker.class), "worker");
system.actorOf(Props.create(WatchActor.class, worker), "watcher");
worker.tell(MyWorker.Msg.WORKING, ActorRef.noSender());
worker.tell(MyWorker.Msg.DONE, ActorRef.noSender());
worker.tell(PoisonPill.getInstance(), ActorRef.noSender());
}
}