by Peter Veentjer
A major benefit of using the Typesafe Stack, including Scala and Akka, is that it simplifies the process of writing concurrent software. This article discusses how the Typesafe Stack, and Akka in particular, approaches shared memory in concurrent applications.
The Java Memory Model
Prior to Java 5, the Java Memory Model (JMM) was ill defined. It was possible to get all kinds of strange results when shared memory was accessed by multiple threads, such as:
With the implementation of JSR 133 in Java 5, a lot of these issues have been resolved. The JMM is a set of rules based on the "happens-before" relation, which constrain when one memory access must happen before another, and conversely, when they are allowed to happen out of order. Two examples of these rules are:
Although the JMM can seem complicated, the specification tries to find a balance between ease of use and the ability to write performant and scalable concurrent data structures.
Actors and the Java Memory Model
With the Actors implementation in Akka, there are two ways multiple threads can execute actions on shared memory:
To prevent visibility and reordering problems on actors, Akka guarantees the following two "happens before" rules:
Both rules only apply for the same actor instance and are not valid if different actors are used.
STM and the Java Memory Model
Akka's Software Transactional Memory (STM) also provides a "happens before" rule:
Currently the Akka STM only supports deferred writes, so the actual writing to shared memory is deferred until the transaction commits. Writes during the transaction are placed in a local buffer (the writeset of the transaction) and are not visible to other transactions. That is why dirty reads are not possible.
How these rules are realized in Akka is an implementation detail and can change over time, and the exact details could even depend on the used configuration. But they will build on the other JMM rules like the monitor lock rule or the volatile variable rule. This means that you, the Akka user, do not need to worry about adding synchronization to provide such a "happens before" relation, because it is the responsibility of Akka. So you have your hands free to deal with your business logic, and the Akka framework makes sure that those rules are guaranteed on your behalf.