Java Memory Model

The Java memory model specifies how and when different threads can see values written to shared variables by other threads, and how to synchronize access to shared variables when necessary. Java memory model which was revised in Java 1.5 is still in use in Java 8. Jenkov has explained very well in his article about JMM. Here is the summary from that article :

  1. Primitive variables inside thread are not shareable, they are kept in thread-stack which is non-shareable between threads.
  2. Objects are created inside heap and heap area is shareable between threads.
  3. Object’s member variable are also stored in heap and hence are shareable even though they are primitive. But all the variable declared inside object’s method are local to that method and they will be store in thread-stack.
  4. Static variables are also stored into heap along with the class definition.

Heap is shareable so synchronization is required.  Lets first understand the synchronization and how lock works.

Synchronization : In an article of “Brian Goetz”, synchronization is explained like this

Java’s primary tool for rendering interactions between threads predictably is the synchronized keyword. Many programmers think of synchronized strictly in terms of enforcing a mutual exclusion semaphore (mutex) to prevent execution of critical sections by more than one thread at a time. Unfortunately, that intuition does not fully describe what synchronized means.

The semantics of synchronized do indeed include mutual exclusion of execution based on the status of a semaphore, but they also include rules about the synchronizing thread’s interaction with main memory. In particular, the acquisition or release of a lock triggers a memory barrier — a forced synchronization between the thread’s local memory and main memory. When a thread exits a synchronized block, it performs a write barrier — it must flush out any variables modified in that block to main memory before releasing the lock. Similarly, when entering a synchronized block, it performs a read barrier — it is as if the local memory has been invalidated, and it must fetch any variables that will be referenced in the block from main memory.

The proper use of synchronization guarantees that one thread will see the effects of another in a predictable manner.

Below examples will show the visibility of variables in Java Memory Model which was explained by Jenkov in his article.

Tagged on:         

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>