原文地址:http://doc.akka.io/docs/akka/2.0.2/intro/getting-started-first-java.html

Introduction

Welcome to the first tutorial on how to get started with Akka and Java. We assume that you already know what Akka and Java are and will now focus on the steps necessary to start your first project.

There are two variations of this first tutorial:

  • creating a standalone project and run it from the command line
  • creating a Maven project and running it from within Maven

Since they are so similar we will present them both.

The sample application that we will create is using actors to calculate the value of Pi. Calculating Pi is a CPU intensive operation and we will utilize Akka Actors to write a concurrent solution that scales out to multi-core processors. This sample will be extended in future tutorials to use Akka Remote Actors to scale out on multiple machines in a cluster.

We will be using an algorithm that is called “embarrassingly parallel” which just means that each job is completely isolated and not coupled with any other job. Since this algorithm is so parallelizable it suits the actor model very well.

Here is the formula for the algorithm we will use:

In this particular algorithm the master splits the series into chunks which are sent out to each worker actor to be processed. When each worker has processed its chunk it sends a result back to the master which aggregates the total result.

Tutorial source code

If you want don’t want to type in the code and/or set up a Maven project then you can check out the full tutorial from the Akka GitHub repository. It is in the akka-tutorials/akka-tutorial-first module. You can also browse it online here, with the actual source code here.

To check out the code using Git invoke the following command and you can then you can navigate down to the tutorial.

On Linux/Unix/Mac systems:

  1. $ git clone git://github.com/akka/akka.git
  2. $ cd akka/akka-tutorials/akka-tutorial-first

On Windows systems:

  1. C:\Users\jboner\src> git clone git://github.com/akka/akka.git
  2. C:\Users\jboner\src> cd akka\akka-tutorials\akka-tutorial-first

Prerequisites

This tutorial assumes that you have Java 1.6 or later installed on you machine and java on your PATH. You also need to know how to run commands in a shell (ZSH, Bash, DOS etc.) and a decent text editor or IDE to type in the Java code.

You need to make sure that $JAVA_HOME environment variable is set to the root of the Java distribution. You also need to make sure that the $JAVA_HOME/bin is on your PATH.

On Linux/Unix/Mac systems:

  1. $ export JAVA_HOME=..root of Java distribution..
  2. $ export PATH=$PATH:$JAVA_HOME/bin

You can test your installation by invoking java:

  1. $ java -version
  2. java version "1.6.0_24"
  3. Java(TM) SE Runtime Environment (build 1.6.0_24-b07-334-10M3326)
  4. Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02-334, mixed mode)

On Windows systems:

  1. C:\Users\jboner\src\akka> set JAVA_HOME=..root of Java distribution..
  2. C:\Users\jboner\src\akka> set PATH=%PATH%;%JAVA_HOME%/bin

You can test your installation by invoking java:

  1. C:\Users\jboner\src\akka> java -version
  2. java version "1.6.0_24"
  3. Java(TM) SE Runtime Environment (build 1.6.0_24-b07-334-10M3326)
  4. Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02-334, mixed mode)

Downloading and installing Akka

To build and run the tutorial sample from the command line, you have to download Akka. If you prefer to use SBT to build and run the sample then you can skip this section and jump to the next one.

Let’s get the akka-2.0.2.zip distribution of Akka from http://akka.io/downloads/ which includes everything we need for this tutorial. Once you have downloaded the distribution unzip it in the folder you would like to have Akka installed in. In my case I choose to install it in /Users/jboner/tools/, simply by unzipping it to this directory.

You need to do one more thing in order to install Akka properly: set the AKKA_HOME environment variable to the root of the distribution. In my case I’m opening up a shell, navigating down to the distribution, and setting theAKKA_HOME variable.

On Linux/Unix/Mac systems:

  1. $ cd /Users/jboner/tools/akka-2.0.2
  2. $ export AKKA_HOME=`pwd`
  3. $ echo $AKKA_HOME
  4. /Users/jboner/tools/akka-2.0.2

On Windows systems:

  1. C:\Users\jboner\src\akka> cd akka-2.0.2
  2. C:\Users\jboner\src\akka\akka-2.0.2> set AKKA_HOME=%cd%
  3. C:\Users\jboner\src\akka\akka-2.0.2> echo %AKKA_HOME%
  4. C:\Users\jboner\src\akka\akka-2.0.2

The distribution looks like this.

On Linux/Unix/Mac systems:

  1. $ ls -1
  2. bin
  3. config
  4. deploy
  5. doc
  6. lib
  7. src

On Windows systems:

  1. C:\Users\jboner\src\akka\akka-2.0.2> dir
  2. bin
  3. config
  4. deploy
  5. doc
  6. lib
  7. src
  • In the bin directory we have scripts for starting the Akka Microkernel.
  • In the config directory we have the Akka conf files.
  • In the deploy directory we can place applications to be run with the microkernel.
  • In the doc directory we have the documentation, API, and doc JARs.
  • In the lib directory we have the Scala and Akka JARs.
  • In the src directory we have the source JARs for Akka.

The only JAR we will need for this tutorial (apart from the scala-library.jar JAR) is the akka-actor-2.0.2.jar JAR in the lib/akka directory. This is a self-contained JAR with zero dependencies and contains everything we need to write a system using Actors.

Akka is very modular and has many JARs for containing different features. The modules are:

  • akka-actor – Actors
  • akka-remote – Remote Actors
  • akka-slf4j – SLF4J Event Handler Listener for logging with SLF4J
  • akka-testkit – Toolkit for testing Actors
  • akka-kernel – Akka microkernel for running a bare-bones mini application server
  • akka-durable-mailboxes – Durable mailboxes: file-based, MongoDB, Redis, Beanstalk and Zookeeper

Downloading and installing Maven

Maven is an excellent build system that can be used to build both Java and Scala projects. If you want to use Maven for this tutorial then follow the following instructions, if not you can skip this section and the next.

First browse to http://maven.apache.org/download.html and download the 3.0.3 distribution.

To install Maven it is easiest to follow the instructions on http://maven.apache.org/download.html#Installation.

Creating an Akka Maven project

If you have not already done so, now is the time to create a Maven project for our tutorial. You do that by stepping into the directory you want to create your project in and invoking the mvn command.

On Linux/Unix/Mac systems:

  1. $ mvn archetype:generate \
  2. -DgroupId=akka.tutorial.first.java \
  3. -DartifactId=akka-tutorial-first-java \
  4. -DarchetypeArtifactId=maven-archetype-quickstart \
  5. -DinteractiveMode=false

On Windows systems:

  1. C:\Users\jboner\src\akka\akka-2.0.2> mvn archetype:generate \
  2. -DgroupId=akka.tutorial.first.java \
  3. -DartifactId=akka-tutorial-first-java \
  4. -DarchetypeArtifactId=maven-archetype-quickstart \
  5. -DinteractiveMode=false

Now we have the basis for our Maven-based Akka project. Let’s step into the project directory.

On Linux/Unix/Mac systems:

  1. $ cd akka-tutorial-first-java

On Windows systems:

  1. C:\Users\jboner\src\akka\akka-2.0.2> cd akka-tutorial-first-java

Here is the layout that Maven created:

  1. akka-tutorial-first-jboner
  2. |-- pom.xml
  3. `-- src
  4. |-- main
  5. | `-- java
  6. | `-- akka
  7. | `-- tutorial
  8. | `-- first
  9. | `-- java
  10. | `-- App.java

As you can see we already have a Java source file called App.java, let’s now rename it to Pi.java.

We also need to edit the pom.xml build file. Let’s add the dependency we need as well as the Maven repository it should download it from. The Akka Maven repository can be found at http://akka.io/releases/ and Typesafe provides http://repo.typesafe.com/typesafe/releases/ that proxies several other repositories, including akka.io. It should now look something like this:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6. <modelVersion>4.0.0</modelVersion>
  7. <name>akka-tutorial-first-java</name>
  8. <groupId>akka.tutorial.first.java</groupId>
  9. <artifactId>akka-tutorial-first-java</artifactId>
  10. <packaging>jar</packaging>
  11. <version>1.0-SNAPSHOT</version>
  12. <url>http://akka.io</url>
  13. <dependencies>
  14. <dependency>
  15. <groupId>com.typesafe.akka</groupId>
  16. <artifactId>akka-actor</artifactId>
  17. <version>2.0.2</version>
  18. </dependency>
  19. </dependencies>
  20. <repositories>
  21. <repository>
  22. <id>typesafe</id>
  23. <name>Typesafe Repository</name>
  24. <url>http://repo.typesafe.com/typesafe/releases/</url>
  25. </repository>
  26. </repositories>
  27. <build>
  28. <plugins>
  29. <plugin>
  30. <groupId>org.apache.maven.plugins</groupId>
  31. <artifactId>maven-compiler-plugin</artifactId>
  32. <version>2.3.2</version>
  33. <configuration>
  34. <source>1.6</source>
  35. <target>1.6</target>
  36. </configuration>
  37. </plugin>
  38. </plugins>
  39. </build>
  40. </project>

Start writing the code

Now it’s about time to start hacking.

We start by creating a Pi.java file and adding these import statements at the top of the file:

  1. import akka.actor.ActorRef;
  2. import akka.actor.ActorSystem;
  3. import akka.actor.Props;
  4. import akka.actor.UntypedActor;
  5. import akka.actor.UntypedActorFactory;
  6. import akka.routing.RoundRobinRouter;
  7. import akka.util.Duration;
  8. import java.util.concurrent.TimeUnit;

If you are using Maven in this tutorial then create the file in the src/main/java/akka/tutorial/first/javadirectory.

If you are using the command line tools then create the file wherever you want. We will create it in a directory called tutorial at the root of the Akka distribution, e.g. in$AKKA_HOME/tutorial/akka/tutorial/first/java/Pi.java.

Creating the messages

The design we are aiming for is to have one Master actor initiating the computation, creating a set of Workeractors. Then it splits up the work into discrete chunks, and sends these chunks to the different workers in a round-robin fashion. The master waits until all the workers have completed their work and sent back results for aggregation. When computation is completed the master sends the result to the Listener, which prints out the result.

With this in mind, let’s now create the messages that we want to have flowing in the system. We need four different messages:

  • Calculate – sent to the Master actor to start the calculation
  • Work – sent from the Master actor to the Worker actors containing the work assignment
  • Result – sent from the Worker actors to the Master actor containing the result from the worker’s calculation
  • PiApproximation – sent from the Master actor to the Listener actor containing the the final pi result and how long time the calculation took

Messages sent to actors should always be immutable to avoid sharing mutable state. So let’s start by creating three messages as immutable POJOs. We also create a wrapper Pi class to hold our implementation:

  1. static class Calculate {
  2. }
  3. static class Work {
  4. private final int start;
  5. private final int nrOfElements;
  6. public Work(int start, int nrOfElements) {
  7. this.start = start;
  8. this.nrOfElements = nrOfElements;
  9. }
  10. public int getStart() {
  11. return start;
  12. }
  13. public int getNrOfElements() {
  14. return nrOfElements;
  15. }
  16. }
  17. static class Result {
  18. private final double value;
  19. public Result(double value) {
  20. this.value = value;
  21. }
  22. public double getValue() {
  23. return value;
  24. }
  25. }
  26. static class PiApproximation {
  27. private final double pi;
  28. private final Duration duration;
  29. public PiApproximation(double pi, Duration duration) {
  30. this.pi = pi;
  31. this.duration = duration;
  32. }
  33. public double getPi() {
  34. return pi;
  35. }
  36. public Duration getDuration() {
  37. return duration;
  38. }
  39. }

Creating the worker

Now we can create the worker actor. This is done by extending in the UntypedActor base class and defining the onReceive method. The onReceive method defines our message handler. We expect it to be able to handle the Work message so we need to add a handler for this message:

  1. public static class Worker extends UntypedActor {
  2. // calculatePiFor ...
  3. public void onReceive(Object message) {
  4. if (message instanceof Work) {
  5. Work work = (Work) message;
  6. double result = calculatePiFor(work.getStart(), work.getNrOfElements());
  7. getSender().tell(new Result(result), getSelf());
  8. } else {
  9. unhandled(message);
  10. }
  11. }
  12. }

As you can see we have now created an UntypedActor with a onReceive method as a handler for the Workmessage. In this handler we invoke the calculatePiFor(..) method, wrap the result in a Result message and send it back to the original sender using getContext().reply(..). In Akka the sender reference is implicitly passed along with the message so that the receiver can always reply or store away the sender reference for future use.

The only thing missing in our Worker actor is the implementation on the calculatePiFor(..) method:

  1. private double calculatePiFor(int start, int nrOfElements) {
  2. double acc = 0.0;
  3. for (int i = start * nrOfElements; i <= ((start + 1) * nrOfElements - 1); i++) {
  4. acc += 4.0 * (1 - (i % 2) * 2) / (2 * i + 1);
  5. }
  6. return acc;
  7. }

Creating the master

The master actor is a little bit more involved. In its constructor we create a round-robin router to make it easier to spread out the work evenly between the workers. Let’s do that first:

  1. workerRouter = this.getContext().actorOf(new Props(Worker.class).withRouter(new RoundRobinRouter(nrOfWorkers)),
  2. "workerRouter");

Now we have a router that is representing all our workers in a single abstraction. So now let’s create the master actor. We pass it three integer variables:

  • nrOfWorkers – defining how many workers we should start up
  • nrOfMessages – defining how many number chunks to send out to the workers
  • nrOfElements – defining how big the number chunks sent to each worker should be

Here is the master actor:

  1. public static class Master extends UntypedActor {
  2. private final int nrOfMessages;
  3. private final int nrOfElements;
  4. private double pi;
  5. private int nrOfResults;
  6. private final long start = System.currentTimeMillis();
  7. private final ActorRef listener;
  8. private final ActorRef workerRouter;
  9. public Master(final int nrOfWorkers, int nrOfMessages, int nrOfElements, ActorRef listener) {
  10. this.nrOfMessages = nrOfMessages;
  11. this.nrOfElements = nrOfElements;
  12. this.listener = listener;
  13. workerRouter = this.getContext().actorOf(new Props(Worker.class).withRouter(new RoundRobinRouter(nrOfWorkers)),
  14. "workerRouter");
  15. }
  16. public void onReceive(Object message) {
  17. // handle messages ...
  18. }
  19. }

A couple of things are worth explaining further.

Note that we are passing in a ActorRef to the Master actor. This is used to report the the final result to the outside world.

But we are not done yet. We are missing the message handler for the Master actor. This message handler needs to be able to react to two different messages:

  • Calculate – which should start the calculation
  • Result – which should aggregate the different results

The Calculate handler is sending out work to all the Worker via its router.

The Result handler gets the value from the Result message and aggregates it to our pi member variable. We also keep track of how many results we have received back, and if that matches the number of tasks sent out, the Master actor considers itself done and sends the final result to the listener. When done it also invokes the getContext().stop(getSelf()) method to stop itself and all its supervised actors. In this case it has one supervised actor, the router, and this in turn has nrOfWorkers supervised actors. All of them will be stopped automatically as the invocation of any supervisor’s stop method will propagate down to all its supervised ‘children’.

Let’s capture this in code:

  1. public void onReceive(Object message) {
  2. if (message instanceof Calculate) {
  3. for (int start = 0; start < nrOfMessages; start++) {
  4. workerRouter.tell(new Work(start, nrOfElements), getSelf());
  5. }
  6. } else if (message instanceof Result) {
  7. Result result = (Result) message;
  8. pi += result.getValue();
  9. nrOfResults += 1;
  10. if (nrOfResults == nrOfMessages) {
  11. // Send the result to the listener
  12. Duration duration = Duration.create(System.currentTimeMillis() - start, TimeUnit.MILLISECONDS);
  13. listener.tell(new PiApproximation(pi, duration), getSelf());
  14. // Stops this actor and all its supervised children
  15. getContext().stop(getSelf());
  16. }
  17. } else {
  18. unhandled(message);
  19. }
  20. }

Creating the result listener

The listener is straightforward. When it receives the PiApproximation from the Master it prints the result and shuts down the ActorSystem.

  1. public static class Listener extends UntypedActor {
  2. public void onReceive(Object message) {
  3. if (message instanceof PiApproximation) {
  4. PiApproximation approximation = (PiApproximation) message;
  5. System.out.println(String.format("\n\tPi approximation: \t\t%s\n\tCalculation time: \t%s",
  6. approximation.getPi(), approximation.getDuration()));
  7. getContext().system().shutdown();
  8. } else {
  9. unhandled(message);
  10. }
  11. }
  12. }

Please note that shutting down the actor system should be done by that part of the application which can safely determine that everything has been said and done. In this case, it is the Listener actor, but in other scenarios it might be the main thread or some other external service. It is by no means required to callsystem.shutdown() from within that system.

Bootstrap the calculation

Now the only thing that is left to implement is the runner that should bootstrap and run the calculation for us. We do that by adding a main method to the enclosing Pi class in which we create a new instance of Pi and invoke method calculate in which we start up the Master actor and wait for it to finish:

  1. public class Pi {
  2. public static void main(String[] args) {
  3. Pi pi = new Pi();
  4. pi.calculate(4, 10000, 10000);
  5. }
  6. // actors and messages ...
  7. public void calculate(final int nrOfWorkers, final int nrOfElements, final int nrOfMessages) {
  8. // Create an Akka system
  9. ActorSystem system = ActorSystem.create("PiSystem");
  10. // create the result listener, which will print the result and shutdown the system
  11. final ActorRef listener = system.actorOf(new Props(Listener.class), "listener");
  12. // create the master
  13. ActorRef master = system.actorOf(new Props(new UntypedActorFactory() {
  14. public UntypedActor create() {
  15. return new Master(nrOfWorkers, nrOfMessages, nrOfElements, listener);
  16. }
  17. }), "master");
  18. // start the calculation
  19. master.tell(new Calculate());
  20. }
  21. }

As you can see the calculate method above it creates an ActorSystem and this is the Akka container which will contain all actors created in that “context”. An example of how to create actors in the container is the‘system.actorOf(...)’ line in the calculate method. In this case we create two top level actors. If you instead where in an actor context, i.e. inside an actor creating other actors, you should use getContext().actorOf(...). This is illustrated in the Master code above.

That’s it. Now we are done.

Before we package it up and run it, let’s take a look at the full code now, with package declaration, imports and all:

  1. /**
  2. * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
  3. */
  4. package akka.tutorial.first.java;
  5. import akka.actor.ActorRef;
  6. import akka.actor.ActorSystem;
  7. import akka.actor.Props;
  8. import akka.actor.UntypedActor;
  9. import akka.actor.UntypedActorFactory;
  10. import akka.routing.RoundRobinRouter;
  11. import akka.util.Duration;
  12. import java.util.concurrent.TimeUnit;
  13. public class Pi {
  14. public static void main(String[] args) {
  15. Pi pi = new Pi();
  16. pi.calculate(4, 10000, 10000);
  17. }
  18. static class Calculate {
  19. }
  20. static class Work {
  21. private final int start;
  22. private final int nrOfElements;
  23. public Work(int start, int nrOfElements) {
  24. this.start = start;
  25. this.nrOfElements = nrOfElements;
  26. }
  27. public int getStart() {
  28. return start;
  29. }
  30. public int getNrOfElements() {
  31. return nrOfElements;
  32. }
  33. }
  34. static class Result {
  35. private final double value;
  36. public Result(double value) {
  37. this.value = value;
  38. }
  39. public double getValue() {
  40. return value;
  41. }
  42. }
  43. static class PiApproximation {
  44. private final double pi;
  45. private final Duration duration;
  46. public PiApproximation(double pi, Duration duration) {
  47. this.pi = pi;
  48. this.duration = duration;
  49. }
  50. public double getPi() {
  51. return pi;
  52. }
  53. public Duration getDuration() {
  54. return duration;
  55. }
  56. }
  57. public static class Worker extends UntypedActor {
  58. private double calculatePiFor(int start, int nrOfElements) {
  59. double acc = 0.0;
  60. for (int i = start * nrOfElements; i <= ((start + 1) * nrOfElements - 1); i++) {
  61. acc += 4.0 * (1 - (i % 2) * 2) / (2 * i + 1);
  62. }
  63. return acc;
  64. }
  65. public void onReceive(Object message) {
  66. if (message instanceof Work) {
  67. Work work = (Work) message;
  68. double result = calculatePiFor(work.getStart(), work.getNrOfElements());
  69. getSender().tell(new Result(result), getSelf());
  70. } else {
  71. unhandled(message);
  72. }
  73. }
  74. }
  75. public static class Master extends UntypedActor {
  76. private final int nrOfMessages;
  77. private final int nrOfElements;
  78. private double pi;
  79. private int nrOfResults;
  80. private final long start = System.currentTimeMillis();
  81. private final ActorRef listener;
  82. private final ActorRef workerRouter;
  83. public Master(final int nrOfWorkers, int nrOfMessages, int nrOfElements, ActorRef listener) {
  84. this.nrOfMessages = nrOfMessages;
  85. this.nrOfElements = nrOfElements;
  86. this.listener = listener;
  87. workerRouter = this.getContext().actorOf(new Props(Worker.class).withRouter(new RoundRobinRouter(nrOfWorkers)),
  88. "workerRouter");
  89. }
  90. public void onReceive(Object message) {
  91. if (message instanceof Calculate) {
  92. for (int start = 0; start < nrOfMessages; start++) {
  93. workerRouter.tell(new Work(start, nrOfElements), getSelf());
  94. }
  95. } else if (message instanceof Result) {
  96. Result result = (Result) message;
  97. pi += result.getValue();
  98. nrOfResults += 1;
  99. if (nrOfResults == nrOfMessages) {
  100. // Send the result to the listener
  101. Duration duration = Duration.create(System.currentTimeMillis() - start, TimeUnit.MILLISECONDS);
  102. listener.tell(new PiApproximation(pi, duration), getSelf());
  103. // Stops this actor and all its supervised children
  104. getContext().stop(getSelf());
  105. }
  106. } else {
  107. unhandled(message);
  108. }
  109. }
  110. }
  111. public static class Listener extends UntypedActor {
  112. public void onReceive(Object message) {
  113. if (message instanceof PiApproximation) {
  114. PiApproximation approximation = (PiApproximation) message;
  115. System.out.println(String.format("\n\tPi approximation: \t\t%s\n\tCalculation time: \t%s",
  116. approximation.getPi(), approximation.getDuration()));
  117. getContext().system().shutdown();
  118. } else {
  119. unhandled(message);
  120. }
  121. }
  122. }
  123. public void calculate(final int nrOfWorkers, final int nrOfElements, final int nrOfMessages) {
  124. // Create an Akka system
  125. ActorSystem system = ActorSystem.create("PiSystem");
  126. // create the result listener, which will print the result and shutdown the system
  127. final ActorRef listener = system.actorOf(new Props(Listener.class), "listener");
  128. // create the master
  129. ActorRef master = system.actorOf(new Props(new UntypedActorFactory() {
  130. public UntypedActor create() {
  131. return new Master(nrOfWorkers, nrOfMessages, nrOfElements, listener);
  132. }
  133. }), "master");
  134. // start the calculation
  135. master.tell(new Calculate());
  136. }
  137. }

Run it as a command line application

If you have not typed in (or copied) the code for the tutorial as$AKKA_HOME/tutorial/akka/tutorial/first/java/Pi.java then now is the time. When that’s done open up a shell and step in to the Akka distribution (cd $AKKA_HOME).

First we need to compile the source file. That is done with Java’s compiler javac. Our application depends on the akka-actor-2.0.2.jar and the scala-library.jar JAR files, so let’s add them to the compiler classpath when we compile the source.

On Linux/Unix/Mac systems:

  1. $ javac -cp lib/scala-library.jar:lib/akka/akka-actor-2.0.2.jar tutorial/akka/tutorial/first/java/Pi.java

On Windows systems:

  1. C:\Users\jboner\src\akka\akka-2.0.2> javac -cp \
  2. lib/scala-library.jar;lib/akka/akka-actor-2.0.2.jar \
  3. tutorial/akka/tutorial/first/java/Pi.java

When we have compiled the source file we are ready to run the application. This is done with java but yet again we need to add the akka-actor-2.0.2.jar and the scala-library.jar JAR files to the classpath as well as the classes we compiled ourselves.

On Linux/Unix/Mac systems:

  1. $ java \
  2. -cp lib/scala-library.jar:lib/akka/akka-actor-2.0.2.jar:. \
  3. akka.tutorial.first.scala.Pi
  4. Pi approximation: 3.1415926435897883
  5. Calculation time: 359 millis

On Windows systems:

  1. C:\Users\jboner\src\akka\akka-2.0.2> java \
  2. -cp lib/scala-library.jar;lib\akka\akka-actor-2.0.2.jar;. \
  3. akka.tutorial.first.scala.Pi
  4. Pi approximation: 3.1415926435897883
  5. Calculation time: 359 millis

Yippee! It is working.

Run it inside Maven

If you used Maven, then you can run the application directly inside Maven. First you need to compile the project.

On Linux/Unix/Mac systems:

  1. $ mvn compile

On Windows systems:

  1. C:\Users\jboner\src\akka\akka-2.0.2> mvn compile

When this in done we can run our application directly inside Maven.

On Linux/Unix/Mac systems:

  1. $ mvn exec:java -Dexec.mainClass="akka.tutorial.first.java.Pi"
  2. ...
  3. Pi approximation: 3.1415926435897883
  4. Calculation time: 359 millis

On Windows systems:

  1. C:\Users\jboner\src\akka\akka-2.0.2> mvn exec:java \
  2. -Dexec.mainClass="akka.tutorial.first.java.Pi"
  3. ...
  4. Pi approximation: 3.1415926435897883
  5. Calculation time: 359 millis

Yippee! It is working.

Overriding Configuration Externally (Optional)

The sample project includes an application.conf file in the resources directory:

  1. akka.actor.deployment {
  2. /master/workerRouter {
  3. # Uncomment the following two lines to change the calculation to use 10 workers instead of 4:
  4. #router = round-robin
  5. #nr-of-instances = 10
  6. }
  7. }

If you uncomment the two lines, you should see a change in performance, hopefully for the better (you might want to increase the number of messages in the code to prolong the time the application runs). It should be noted that overriding only works if a router type is given, so just uncommenting nr-of-instances does not work; see Routing (Java) for more details.

Note

Make sure that your application.conf is on the class path when you run the application. If running from inside Maven that should already be the case, otherwise you need to add the directory containing this file to the JVM’s -classpath option.

Conclusion

We have learned how to create our first Akka project using Akka’s actors to speed up a computation-intensive problem by scaling out on multi-core processors (also known as scaling up). We have also learned to compile and run an Akka project using either the tools on the command line or the SBT build system.

If you have a multi-core machine then I encourage you to try out different number of workers (number of working actors) by tweaking the nrOfWorkers variable to for example; 2, 4, 6, 8 etc. to see performance improvement by scaling up.

Happy hakking.

转载于:https://www.cnblogs.com/davidwang456/p/5087032.html

akka---Getting Started Tutorial (Java): First Chapter相关推荐

  1. AKKA文档(java版)——准备开始

     http://ifeve.com/akka-doc-java-getting-started/ AKKA文档(java版)--准备开始 原文:http://doc.akka.io/docs/ak ...

  2. java mongodb开发_Java Tutorial:Java操作MongoDB入门

    [IT168 技术]个人编译能力有限,以下提供英汉对照,欢迎讨论指正. Introduction 介绍 This page is a brief overview of working with th ...

  3. AKKA文档(java)——术语,概念

    原文:http://doc.akka.io/docs/akka/2.3.6/general/terminology.html 译者:吴京润 本章我们试图建立一个通用的术语列表,用来定义有关并发和分布式 ...

  4. Akka in JAVA(三)

    2019独角兽企业重金招聘Python工程师标准>>> Akka in JAVA(三) 上两个部分讲了Akka的基本知识和常见的用法.接下来讲一讲Akka的远程调用以及集群的使用.因 ...

  5. java akka_AKKA文档(java版)——什么是AKKA?

    可扩展的实时事务处理 我们相信编写并发.容错.可扩展的应用相当的困难.盖因大多数时候我们一直在使用错误的工具和错误的抽象等级.AKKA就是为了改变这一切的.我们利用角色模型提升了抽象等级,并且提供了一 ...

  6. Java官方教程Java Tutorial

    概述 The Java Tutorials have been written for JDK 8. Examples and practices described in this page don ...

  7. [读书笔记]Core Java: Volume I - Fundamentals Chapter 1

    Title: Core Java - Volume I Fundamentals Edition: Eleventh Edition Author: Cay S. Horstmann 文章目录 Pre ...

  8. akka for java

    目前火热的两大计算框架 Spark 和 Flink 底层的通讯原理使用的都是 akka(当前的 Spark 已经背叛了akka,转投 netty),而网上对 akka 的教程是在太少,推荐 githu ...

  9. java akka 教程_快速入门 Akka Java 指南

    快速入门 Akka Java 指南 Akka 是一个用于在 JVM 上构建高并发.分布式和容错的事件驱动应用程序的运行时工具包.Akka 既可以用于 Java,也可以用于 Scala.本指南通过描述 ...

最新文章

  1. LintCode 用递归打印数字
  2. (ZT)大学里如何学习 ?
  3. 华为2019暑期实习笔试题
  4. 嗅探(被动嗅探)与ARP欺骗(主动嗅探)详解
  5. 第七届山东省Acm程序设计竞赛赛后总结
  6. JavaScript:综合案例---房贷计算器的实现
  7. mysqljoin的原理和优化
  8. NOIP2016愤怒的小鸟 题解报告 【状压DP】
  9. 鼠标悬停一段时间再触发事件
  10. OpenStack Queens 女王新神器 — 卷多重挂载
  11. php进程池不释放,php-fpm 进程池优化方法
  12. 【3dmax千千问】初学3dmax插件神器第16课|VRAY学习教程|疯狂模渲大师怎么使用VRAY渲染器?食住玩3dmax入门到精通进阶教程
  13. MATLAB Codesys,CoDeSys学习日记(一)
  14. Tensorflow (2): tf.slim库解读
  15. 20220626——每日推送信息API总结
  16. ViewPager设置页面缩放
  17. 简易云台制作记录(内含MPU6050角度的求法)
  18. TKO 2-4基本贪心之求最小数字 3183
  19. Cdn英文的读音音标_我来告诉你,自然拼读和音标,孩子究竟该学哪个?!
  20. PPT学习整理(一)默认设置

热门文章

  1. 违反了primarykey约束怎么解决_前期物业服务合同对主业有约束力吗?
  2. 电脑服务器不稳定怎么办,网速不稳定怎么办? 网速不稳定的原因与解决办法-电脑教程...
  3. java 智能家居管理系统_智能家居系统手机客户端应用源码
  4. 之江汇空间如何加音乐背景_从脚本到成品,教你如何快速制作出创意又浪漫的婚礼视频...
  5. pandas 删除有缺失值的个案,做回归分析
  6. docker 训练深度学习_利用RGB图像训练MultiModality的深度学习模型进行图像分割
  7. Java中对象的实例化顺序
  8. fguillot json rpc_使用Hyperf框架搭建jsonrpc服务
  9. c++ getline 读不到东西_C++ getline()函数问题
  10. linux mysql libc.so_mysql-arm-linux-gcc编译报错:libc.soformatnotrecognized.