The java memory model defines how the threads interact with memory. In multiprocessor generally we have more than one layer of the memory cache. Having the memory cache can tremendously improve the performance. This opens the complexity of how two processors are going to interact with the same memory location.A memory model needs to be defined at the processor level so that sufficient terms and conditions can be visible to the processors so that the memory they use can be used to write.
Java includes several language constructs, including volatile, final, and synchronized, which are intended to help the programmer describe a program's concurrency requirements to the compiler. 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
The JSR 133 laid the new foundation for the Java Memory Model , more details can be found at --> http://jcp.org/en/jsr/detail?id=133
Few prospects addressed by JSR 133
- It should be possible to design correct, high performance JVM implementations across a wide range of popular hardware architectures
- The semantics of correctly synchronized programs should be as simple and intuitive as possible.
- A new guarantee of initialization safety should be provided. If an object is properly constructed (which means that references to it do not escape during construction), then all threads which see a reference to that object will also see the values for its final fields that were set in the constructor, without the need for synchronization.
- There should be minimal impact on existing code.
- Preserving existing safety guarantees, like type-safety, and strengthening others
Lets find out what compelled for the formation of JSR 133.
The old memory model treated the final attribute a bit different from any other variable, the only way was synchronization between threads to see the value of the final attribute written by constructor. It was possible for a thread to see the default value and some point later see the updated value written by the constructor. It raised security concerns for immutable objects like String as change of value can happen.
lets see an example of how final fields can appear to change their values in old memory model. Lets take the String as example, it can be implemented as as object with three different fields a character array, an offset into that array and the length. For example the method String.substring() can be implemented by creating a new string which shares the same character array with the original String and merely differs in the length and offset fields. For a String, these fields are all final fields.
String s = "/test/data/";
String s1= s.substring(5);
The string s1 will have an offset of 5 and a length of 5. But, under the old model, it was possible for another thread to see the offset as having the default value of 0, and then later see the correct value of 5, it will appear as if the string "/test" changes to "/data".
volatile writes were reordered with non volatile read and writes which was very inconsistent creating a lot of confusion about the behavior of volatile.
Lets explore a bit about what is meant by reordering in the JMM. Reordering is access to program variables like static fields, instance object fields, etc which may differ in order of execution than what was specified in the program. The compiler can do the ordering of instruction in an optimized manner. The processor can execute the same in different order based on certain circumstances. The data can be moved to register , cpu cache and main memory in a different order than what was specified in the program.
Synchronization coming soon
No comments:
Post a Comment