Articles : The Java Memory Model Explained :

Surprises in the Memory Model

The sample shown in listing 1 was one of the surprises of memory model. There are a few more, which are interesting. The Java language specification assures us that strings are immutable, so most operations on a string destroy the original object and create a new one. But in reality the compiler can optimize the operation and reuse the same memory as the original string. For instance we have a string ‘String stringSample = "javaboutique";’ stored in memory at memory location m1. The compiler will store this String in memory as origin location = m1 and offset = 12. Now when an operation ‘stringSample = stringSample.substring(4);’ is done, stringSample will contain "boutique". As per the Java specification we would assume that stringSample will be moved to a new location m2 and the old memory location is left for the garbage collector, but compilers can reuse the same memory location and update the offsets. So the new string after the sub string operation would read as origin location = m1+4 and offset = 8. This does not break the Java specification, as the old reference is lost and a new reference is created with a new origin location and a new offset. The problem is when two threads try to access this string at the same time; the second thread might get the wrong starting location. Synchronizing these methods would alleviate the problem.

Final Fields

Java provides for final fields, which are initialized once and are never changed for the life of the object instance. Unlike normal fields, compilers can cache final fields into registers and read from there without reloading them from memory again. In the case of normal fields values can be cached into registers but need to be synchronized with the value in memory when a read is done.

Final fields are of great value in multi-threaded environments as programmers can use them as thread safe immutable objects, which do not need synchronization. Since an immutable field cannot be modified there is a guarantee that the field will not behave erratically even in a data race condition.

Final fields can be initialized either directly in the class when they are declared or through the constructor of the class. According to the Java specification an object is deemed as completely initialized only when the constructor of the class has completed execution. Since the final variables are initialized in the constructor there is a guarantee that the final field is initialized and available to threads with the correct value. The Java memory model ensures that threads get access to final fields only after the object is completely initialized. The Java memory model ensures this by freezing the final field when the constructor for the class exits normally. In the case of constructors calling their super classes final field freeze takes place when the last invoked constructor exits normally.

A final field is considered unchangeable after it is first initialized to a value, but there could be situations when a final field needs to be modified after it is created. One of the situations is during deserialization (reverse of serialization). During deserialization the system will need to change the value of a final field after it has been initialized and frozen. During deserialization the object is created first and then the field values are set. In this case the freeze on a final field occurs only after the constructor has exited and the final fields have been set. So the object should be made unavailable to all threads till the final fields have been set into the object.

Conclusion

The JSR 133 (Java Memory model and thread specification) is not intended as enhancement JSR or a new feature. The memory Model spec should be seen as an addendum to the original Java language specification. The specification does not introduce any new concepts or provide new functionality but serves more like a clarification to the original Java specification. Though a good effort has been made to clarify how threads work and how memory operates, the specification still leaves some questions unanswered. Most of the unanswered questions are centered on how compilers make optimizations to programs and order instructions within a program and how these changes affect the memory. The individual JVM implementers best answer these questions, as they are the ones who use these optimizations within the JVM. Though the specification does not clearly state how the threads are handled in individual JVM implementations, it provides details on what a programmer can expect when dealing with threads.

Benoy Jose is a web developer with over six years of experience in J2EE and Microsoft technologies. He is a Sun Certified programmer and enjoys writing technical and non-technical articles for various magazines.


Print Article

How to Add Java Applets to Your Site

New on the Java Boutique:

New Review:

Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling API boasts simplicity, ease-of-integration, a well-rounded feature set, and it's free!

New Applet:

Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA sequences into three useful formats.

Elsewhere on internet.com:

WebDeveloper Java
Lots of Java information on webdeveloper.com

WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.

ScriptSearch Java
Hundreds of free Java code files to download.

jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.