Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Volatile keyword in java under the hood

I have had a little argument with my teacher about the volatile keyword in java. Is it right to say that when a variable is declared as a volatile:

The value of this variable will never be cached thread-locally: all reads and writes will go straight to the "main memory".

My teachers opinion is that:

volatile keyword does not promise the value of the variable will be saved in the main memory.

Can someone resolve our conflict? Thank you!

like image 437
Ron Badur Avatar asked Mar 14 '17 09:03

Ron Badur


3 Answers

For the exact meaning of keywords such as volatile, look at the Java Language Specification to see the official meaning.

JLS paragraph 8.3.1.4 explains what volatile means:

A field may be declared volatile, in which case the Java Memory Model ensures that all threads see a consistent value for the variable (§17.4).

Paragraph 17.4 explains the Java Memory Model. The memory model gives you certain guarantees about what happens to data after each statement in a program.

If you study that carefully, you'll find that volatile means that if you write to a volatile variable, you have the guarantee that other threads will see what was written. How this is implemented in practice is deliberately not specified. It may be implemented by forcing a write to main memory, but JVM implementers are free to choose a different, possibly more efficient mechanism.

So, strictly speaking, your teacher is right. It does not necessarily mean that the value is written to main memory; although in practice this might well be the case - but it depends on the particular JVM implementation.

like image 21
Jesper Avatar answered Oct 21 '22 17:10

Jesper


What volatile does is to ignore all local CPU caches; or equivalently, refresh the cache line containing that volatile variable to be refreshed from main memory. Thus as the documentation suggests, it makes sure all reads directly read up from main memory and all writes go directly to the main memory.

In addition to this, volatile also have the atomic operation guarantee. It makes sure the variable prefixed by this keyword would be read or written in full as if it's a single instruction. (as in the contrast, you won't worry a 64-bit long integer written by 2 threads end up with the first 32-bit from one thread and the 2nd 32-bit from another thread.) Thus in some certain situation e.g. if you use volatile on a 64 bit long integer on a 32 bit machine, the JVM might need to do more than just a "volatile" instruction. Some more documentations are at https://blogs.oracle.com/dave/entry/java_memory_model_concerns_on .

To your specific question.

  • On reading a volatile in Java, it makes sure the value of the variable is from main memory.
  • On writing a volatile in Java, it makes sure the value of the variable is written to the main memory.

Having said the above - this is from a "logical" point of view. In the reality, modern CPUs employ complex caching policy and it can sometimes guarantee the above is true without actually writing to the main memory. However it only does so on realizing the same effect can absolutely be achieved as a performance optimization step. But I think this is beyond the scope of the discussion.

like image 136
Alex Suo Avatar answered Oct 21 '22 16:10

Alex Suo


I'll just quote two paragraphs from docs

first

A field may be declared volatile, in which case the Java Memory Model ensures that all threads see a consistent value for the variable (§17.4).

second

The memory model describes possible behaviors of a program. An implementation is free to produce any code it likes, as long as all resulting executions of a program produce a result that can be predicted by the memory model.

This provides a great deal of freedom for the implementor to perform a myriad of code transformations, including the reordering of actions and removal of unnecessary synchronization.


Now If you will refer to most of the tutorials regarding votatile keyword in java, most of them will suggest the same thing as you suggested, i.e., The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory".

But docs make no guarantee about it. Although it never denies it as well. It just says this is the possbile behaviour.

So I would say that your teacher is correct. According to docs (and not the most tutorials other than docs), Volatile keyword definitely does not promise that the value of the variable will be saved in the main memory.

However, this doesn't makes you wrong, it all depends upon the JVM implementation.

like image 36
Raman Sahasi Avatar answered Oct 21 '22 16:10

Raman Sahasi