Akka框架准备了一个叫做“收件箱”的组件,使用收件箱,可以很方便地对Actor进行消息发送和接收,大大方便了应用程序与Actor之间的交互。
下面定义了当前示例中唯一一个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 onReceive(Object msg) throws Exception {
if(msg == Msg.WORKING) {
//System.out.println("I am working");
log.info("I am working");
}
if(msg == Msg.DONE) {
//System.out.println("Stop working");
log.info("Stop working");
}
if(msg == Msg.CLOSE) {
//System.out.println("I will shutdown");
log.info("I will shutdown");
getSender().tell(Msg.CLOSE, getSelf());
getContext().stop(getSelf());
} else
unhandled(msg);
}
}
上述代码中,MyWorker会根据收到的消息打印自己的工作状态。当接收到CLOSE消息时,会关闭自己,结束运行。
而在本例中,与整个MyWorker交互的是一个邮箱:
public static void main(String[] args) {
ActorSystem system = ActorSystem.create("inboxdemo",ConfigFactory.load("sample.conf"));
ActorRef worker = system.actorOf(Props.create(MyWorker.class), "worker");
final Inbox inbox = Inbox.create(system);
inbox.watch(worker);
inbox.send(worker, MyWorker.Msg.WORKING);
inbox.send(worker, MyWorker.Msg.DONE);
inbox.send(worker, MyWorker.Msg.CLOSE);
while(true) {
Object msg = inbox.receive(Duration.create(1, TimeUnit.SECONDS));
if(msg == MyWorker.Msg.CLOSE) {
System.out.println("My worker is Closing");
} else if(msg instanceof Terminated) {
System.out.println("My worker is dead");
system.shutdown();
break;
} else {
System.out.println(msg);
}
}
}
上述代码中,第5行,根据ActorSystem构造了一个与之绑定的邮箱Inbox。接着使用邮箱监视MyWorker(第6行),这样就能在MyWorker停止后得到一个消息通知。第7~9行,通过邮箱向MyWorker发送消息。
在第11~21行,输出如下:
MyWorker is starting
MyWorker is stopping
[INFO] [01/13/2017 14:16:52.565] [inboxdemo-akka.actor.default-dispatcher-3] [akka://inboxdemo/user/worker] I am working
[INFO] [01/13/2017 14:16:52.568] [inboxdemo-akka.actor.default-dispatcher-3] [akka://inboxdemo/user/worker] Stop working
[INFO] [01/13/2017 14:16:52.568] [inboxdemo-akka.actor.default-dispatcher-3] [akka://inboxdemo/user/worker] I will shutdown
My worker is Closing
My worker is dead
上述输出的第3~5行为MyWorker的输出日志,表示MyWorker Actor的工作状态。后两行为主函数main()中对MyWorker消息的处理。