下面就Akka的一个java demo来说明Akka 如何运作的。
下载地址为: http://akka.io/downloads/. 我下载的是 Akka的2.3.15
解压这个压缩包,准备拷贝相关的jar包到自己的工程
首先导入包
这里,首先贴入源码,然后再对源码进行分析。 源码有4个文件,主要完成的功能是,主程序创建ActorSystem,并且生成Actor1(CreationActor),这个Actor1,根据随机得到的消息,循环创建线程,每个线程都创建Actor2(CalculatorActor),并发不同的消息给Actor2 告诉这些第二层Actor要做什么。 这些Actor2 做完自己的事情后,发消息给Actor1,告诉自己完成了,Actor1 收到消息后,打印结果是什么,并结束线程。
整个业务大致可以用下面图来表示:(左边是示意图,右边是类图)
Op.java
<span style="font-family:Microsoft YaHei;font-size:14px;">package com.cwqsolo.study.akka.demo; import java.io.Serializable; //Op 类是操作类,分别包含了 加减乘除类和加减乘除结果类 public class Op { public interface MathOp extends Serializable { } public interface MathResult extends Serializable { } //加法操作 static class Add implements MathOp { private static final long serialVersionUID = 1L; private final int n1; private final int n2; public Add(int n1, int n2) { this.n1 = n1; this.n2 = n2; } public int getN1() { return n1; } public int getN2() { return n2; } } static class AddResult implements MathResult { private static final long serialVersionUID = 1L; private final int n1; private final int n2; private final int result; public AddResult(int n1, int n2, int result) { this.n1 = n1; this.n2 = n2; this.result = result; } public int getN1() { return n1; } public int getN2() { return n2; } public int getResult() { return result; } } //减法操作 static class Subtract implements MathOp { private static final long serialVersionUID = 1L; private final int n1; private final int n2; public Subtract(int n1, int n2) { this.n1 = n1; this.n2 = n2; } public int getN1() { return n1; } public int getN2() { return n2; } } static class SubtractResult implements MathResult { private static final long serialVersionUID = 1L; private final int n1; private final int n2; private final int result; public SubtractResult(int n1, int n2, int result) { this.n1 = n1; this.n2 = n2; this.result = result; } public int getN1() { return n1; } public int getN2() { return n2; } public int getResult() { return result; } } //乘法操作 static class Multiply implements MathOp { private static final long serialVersionUID = 1L; private final int n1; private final int n2; public Multiply(int n1, int n2) { this.n1 = n1; this.n2 = n2; } public int getN1() { return n1; } public int getN2() { return n2; } } static class MultiplicationResult implements MathResult { private static final long serialVersionUID = 1L; private final int n1; private final int n2; private final int result; public MultiplicationResult(int n1, int n2, int result) { this.n1 = n1; this.n2 = n2; this.result = result; } public int getN1() { return n1; } public int getN2() { return n2; } public int getResult() { return result; } } // 除法操作 static class Divide implements MathOp { private static final long serialVersionUID = 1L; private final double n1; private final int n2; public Divide(double n1, int n2) { this.n1 = n1; this.n2 = n2; } public double getN1() { return n1; } public int getN2() { return n2; } } static class DivisionResult implements MathResult { private static final long serialVersionUID = 1L; private final double n1; private final int n2; private final double result; public DivisionResult(double n1, int n2, double result) { this.n1 = n1; this.n2 = n2; this.result = result; } public double getN1() { return n1; } public int getN2() { return n2; } public double getResult() { return result; } } }</span>CalculatorActor.java
<span style="font-family:Microsoft YaHei;font-size:14px;">package com.cwqsolo.study.akka.demo; import akka.actor.UntypedActor; public class CalculatorActor extends UntypedActor { @Override public void onReceive(Object message) { if (message instanceof Op.Add) { Op.Add add = (Op.Add) message; System.out.println("Calculating " + add.getN1() + " + " + add.getN2()); Op.AddResult result = new Op.AddResult(add.getN1(), add.getN2(), add.getN1() + add.getN2()); getSender().tell(result, getSelf()); } else if (message instanceof Op.Subtract) { Op.Subtract subtract = (Op.Subtract) message; System.out.println("Calculating " + subtract.getN1() + " - " + subtract.getN2()); Op.SubtractResult result = new Op.SubtractResult(subtract.getN1(), subtract.getN2(), subtract.getN1() - subtract.getN2()); getSender().tell(result, getSelf()); } else if (message instanceof Op.Multiply) { Op.Multiply multiply = (Op.Multiply) message; System.out.println("Calculating " + multiply.getN1() + " * " + multiply.getN2()); Op.MultiplicationResult result = new Op.MultiplicationResult( multiply.getN1(), multiply.getN2(), multiply.getN1() * multiply.getN2()); getSender().tell(result, getSelf()); } else if (message instanceof Op.Divide) { Op.Divide divide = (Op.Divide) message; System.out.println("Calculating " + divide.getN1() + " / " + divide.getN2()); Op.DivisionResult result = new Op.DivisionResult(divide.getN1(), divide.getN2(), divide.getN1() / divide.getN2()); getSender().tell(result, getSelf()); } else { unhandled(message); } } }</span>CreationActor.java
<span style="font-family:Microsoft YaHei;font-size:14px;">package com.cwqsolo.study.akka.demo; import akka.actor.ActorRef; import akka.actor.Props; import akka.actor.UntypedActor; //创建Actor public class CreationActor extends UntypedActor { @Override public void onReceive(Object message) throws Exception { if (message instanceof Op.MathOp) { ActorRef calculator = getContext().actorOf( Props.create(CalculatorActor.class)); calculator.tell(message, getSelf()); } else if (message instanceof Op.MultiplicationResult) { Op.MultiplicationResult result = (Op.MultiplicationResult) message; System.out.printf("Mul result: %d * %d = %d\n", result.getN1(), result.getN2(), result.getResult()); getContext().stop(getSender()); } else if (message instanceof Op.DivisionResult) { Op.DivisionResult result = (Op.DivisionResult) message; System.out.printf("Div result: %.0f / %d = %.2f\n", result.getN1(), result.getN2(), result.getResult()); getContext().stop(getSender()); } else { unhandled(message); } } }</span>CreationApplication.java
<span style="font-family:Microsoft YaHei;font-size:14px;">package com.cwqsolo.study.akka.demo; import static java.util.concurrent.TimeUnit.SECONDS; import java.util.Random; import scala.concurrent.duration.Duration; import akka.actor.ActorRef; import akka.actor.ActorSystem; import akka.actor.Props; import com.typesafe.config.ConfigFactory; public class CreationApplication { public static void main(String[] args) { if (args.length == 0 || args[0].equals("CalculatorWorker")) startRemoteWorkerSystem(); if (args.length == 0 || args[0].equals("Creation")) startRemoteCreationSystem(); } public static void startRemoteWorkerSystem() { ActorSystem.create("CalculatorWorkerSystem", ConfigFactory.load(("calculator"))); System.out.println("Started CalculatorWorkerSystem"); } public static void startRemoteCreationSystem() { final ActorSystem system = ActorSystem.create("CreationSystem", ConfigFactory.load("remotecreation")); final ActorRef actor = system.actorOf(Props.create(CreationActor.class), "creationActor"); System.out.println("Started CreationSystem"); final Random r = new Random(); system.scheduler().schedule(Duration.create(1, SECONDS), Duration.create(1, SECONDS), new Runnable() { @Override public void run() { if (r.nextInt(100) % 2 == 0) { actor.tell(new Op.Multiply(r.nextInt(100), r.nextInt(100)), null); } else { actor.tell(new Op.Divide(r.nextInt(10000), r.nextInt(99) + 1), null); } } }, system.dispatcher()); } }</span>
源码运行的结果为:
Started CalculatorWorkerSystem
Started CreationSystem
Calculating 4915.0 / 63
Div result: 4915 / 63 = 78.02
Calculating 1409.0 / 15
Div result: 1409 / 15 = 93.93
Calculating 99 * 64
Mul result: 99 * 64 = 6336
1、只能创建一个WorkerSystem
ActorSystem.create("CalculatorWorkerSystem", ConfigFactory.load(("calculator")));2、 只能创建一个ActorSystem
final ActorSystem system = ActorSystem.create("CreationSystem", ConfigFactory.load("remotecreation"));3、创建Actor
final ActorRef actor = system.actorOf(Props.create(CreationActor.class), "creationActor");4、发送消息给这个Actor
actor.tell(new Op.Multiply(r.nextInt(100), r.nextInt(100)), null);5、 Actor 返回消息给上层调用的Actor
getSender().tell(result, getSelf());