The Java memory model defines how the Java virtual machine works with the computer’s memory (RAM). Understanding of Java Memory Model is very important if you want to develop a highly concurrent application.
Below are the important points regarding the Java Memory Model:
1. The Java programming language specifies a memory model for shared memory multiprocessors that supports high-performance implementations.
2. Memory that can be shared between threads is called shared memory or heap memory. All instance fields, static fields, and array elements are stored in heap memory.
3. The Java Memory Model defines how threads in Java interact through memory. It ensures that all threads see a consistent value for the variable.
4. The Java Memory Model describes, given a program and an execution trace of that program, whether the execution trace is a legal execution of the program.
5. The Java Memory Model provides a great deal of freedom for the implementer to perform a myriad of code transformations.
6. It must be possible for the Java Memory Model to decide when it can commit actions that take place in a finalizer.
7. Local variables, formal method parameters, and exception handler parameters are never shared between threads and are unaffected by the memory model.
8. The Java Memory Model defines the behavior of volatile and synchronized, and, more importantly, ensures that a correctly synchronized Java program runs correctly on all processor architectures.
9. The Java Memory Model specifies when the actions of one thread on memory are guaranteed to be visible to another.
The Java Memory Model define the allowed program outcomes by describing what executions are conforming by introducing actions, orders over actions, and consistency rules that govern what actions+orders+constraints constitute a valid execution. When a the result of a program can be explained by some valid execution, then this result is allowed under Java Memory Model.
Below are the orders and actions under Java Memory Model:
Program order (PO): it defines a total order of actions within each thread. This order provides a connection between the single-threaded execution of the program, and the actions it generates. Executions that have program orders inconsistent with the original programs cannot be used to reason about that particular program’s outcomes.
Synchronization order (SO): it defines a total order over synchronization actions. It comes with two important consistency rules:
1. SO consistency: all reads that come later in the synchronization order see the last write to that location. This property disallows racy results over synchronization actions in conforming executions.
2. SO-PO consistency: the order of synchronization actions in SO within a single thread is consistent with PO in that thread. This means a conforming execution should have the order of SO to agree with PO.
SO consistency and SO-PO consistency mean that in all conforming executions synchronized actions appear sequentially consistent.
Synchronized-with order (SW): a suborder of SO that covers the pairs of synchronization actions that “see” each other. This order serves as the connection bridge between different threads.
Happens-before order (HB): the transitive closure of the union of PO and SW. Unlike SO, HB is a partial order, and only relates some actions, not every pair of actions. Also, unlike SO, HB is able to relate the actions that are not synchronization actions, which allows us to cover all important actions with ordering guarantees. HB comes with the following important consistency rule:
HB consistency: every read can see either the latest write in the happens-before order (notice the symmetry with SO here), or any other write that is not ordered by HB (this allows races).
Causality rules: this is an additional verification on otherwise conforming executions, to rule out causality loops. This is verified by a special process of “committing” the actions from the execution and verifying that no self-justification of actions takes place.
Final field rules: this is tangential to the rest of the model, and describes additional constraints imposed by final fields, e.g. additional happens-before ordering between final field stores and their associated reads.