Parallelism simplified by Akka in Java30 Aug 2013
I have bean writing applications in Java EE environment for some time now and I didn’t need to worry about creating own threads. When I needed to create and manage my own threads it always felt wrong because of to much low level programming. Then I came across akka and wanted to try it out.
What is Akka?
Quote from akka.io “We believe that writing correct concurrent, fault-tolerant and scalable applications is too hard. Most of the time it’s because we are using the wrong tools and the wrong level of abstraction. Akka is here to change that. Using the Actor Model we raise the abstraction level and provide a better platform to build correct, concurrent, and scalable applications. For fault-tolerance we adopt the “Let it crash”; model which the telecom industry has used with great success to build applications that self-heal and systems that never stop. Actors also provide the abstraction for transparent distribution and the basis for truly scalable and fault-tolerant applications.”
For the purpose of the sample we have a trivial working unit that simulates CPU intensive task that can find a factorial for a large number. We assume that we need to find factorials for many different numbers, for the purpose of consistency the number is now fixed.
The most simple way of implementing this is to loop through the numbers and calculate the factorial for them, like this.
This is a simple solution that works well, but the problem with it is that the processing speed entirely depends on one thread on the local machine even though the messages could be processed simultaneously. It is possible to solve this problem in many different ways, for example by using a container managed environment. Although it can solve the problem it brings complexity and overhead to the project. Another way is to use threading, but that means working on a low level coding and it does not allow distributed scaling. But there is also Akka way.
Akka can be used as a library like in this sample, as a microkernel or part of the Typesafe Platform. This sample consists of four parts: bootstrapping Akka (starting ActorSystem), master actor that handles the messages, worker actor that handles the calculating process and at last there are triggers (messages).
Bootstrapping Akka consists of starting the ActorSystem, creating the master actor and telling it to start processing.
Master actor is responsible for processing the messages, meaning telling the Worker actor to calculate the factorial. Akka has different ways to scale, in this sample RoundRobinRouter is being used so that multiple Worker actors can do their work at once. Master worker is also responsible for receiving the results from the Worker actors and knowing when all messages are processed.
Worker actor is responsible for the actual factorial calculation and returning a response to the parent (master actor) when done.
For communication between actors Akka uses triggers (messages) that are immutable objects.
This is all the code that is needed to take advantage of parallelism. If local scaling is not enough Akka also has a simple distributed solution build in that allows the Worker actor to be run remotely without changing the code.
Speed: Java way vs Akka way
|Messages||Java (milliseconds)||Akka quad (milliseconds)|
This sample shows that it is quite easy to take advantage of parallelism by using Akka to speed up the application. Because Akka is on a higher abstraction level than threads themselves it is possible to speed up the application even further by changing the actors number or by running it distributed.
The working project and the complete code can be found on github.