《Java高并发程序设计》学习 --7.3 Akka之Actor的生命周期

45 篇文章 0 订阅

一个Actor在actorOf()函数被调用后开始建立,Actor实例创建后,会回调preStart()方法。在这个方法里,我们可以进行一些资源的初始化工作。在Actor的工作过程中,可能会出现一些异常,这种情况下,Actor会需要重启。当Actor被重启时,会回调preRestart()方法(在老的实例上),接着系统会创建一个新的Actor对象实例(但它们都表示同一个Actor)。当新的Actor实例创建后,会回调postRestart()方法,表示启动完成,同时新的实例将会代替旧的实例。停止一个Actor也有很多方式,可以调用stop()方法或者给Actor发送一个PosionPill(毒药丸)。Actor停止时,postStop()方法会被调用,同时这个Actor的监视着会收到一个Terminated消息。
下面建立一个带有生命周期回调函数的Actor:
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("MyWorker is stopping");
	}
	@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 shutdown");
			getSender().tell(Msg.CLOSE, getSelf());
			getContext().stop(getSelf());
		} else {
			unhandled(msg);
		}
	}
}
上述代码定义了一个名为MyWorker的Actor。它重载了preStart()和postStop()两个方法。一般来说,可以使用preStart()来初始化一些资源,使用postStop()来进行资源的释放。这个Actor很简单,当它收到WORKING消息时,就打印“I am working”,收到DONE消息时,打印“Stop working”。
接着,我们为MyWorker指定一个监视者,监视者就如同一个劳动监工,一旦MyWorker因为意外停止工作,监视者就会收到一个通知。
public class WatchActor extends UntypedActor {
	private final LoggingAdapter log = Logging.getLogger(getContext().system(), this);
	public WatchActor(ActorRef ref) {
		getContext().watch(ref);
	}
	@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();
		}
	}
}
上述代码定义了一个监视者WatchActor,它本质上也是一个Actor,但不同的是,它会在它的上下文中watch一个Actor。如果将来找个被监视的Actor的退出终止,WatchActor就能收到一条Terminated消息。在这里,将打印终止消息Terminated中的相关Actor路径,并且关闭整个ActorSystem。
主函数如下:
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());
	}
}
上述代码中,首先创建ActorSystem全局实例,接着创建MyWorker和WatchActor。第6行的Props.create()方法,它的第1个参数为要创建的Actor类型,第2个参数为这个Actor的构造函数的参数(在这里,就是要调用WatchActor的构造函数)。接着,向MyWorker先后发送WORKING和DONE两条消息。最后在第9行,发送一条特殊的消息PoisonPill。PoisonPill就是毒药丸,它会直接毒死接收方,让其终止。

注:本篇博客内容总结自《 Java 高并发程序设计》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值