Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does volatile actually work?

Marking a variable as volatile in Java ensures that every thread sees the value that was last written to it instead of some stale value. I was wondering how this is actually achieved. Does the JVM emit special instructions that flush the CPU cashes or something?

like image 591
fredoverflow Avatar asked Apr 22 '10 20:04

fredoverflow


People also ask

How does volatile work in Java?

For Java, “volatile” tells the compiler that the value of a variable must never be cached as its value may change outside of the scope of the program itself.

How does volatile keyword work in C?

The volatile keyword is intended to prevent the compiler from applying any optimizations on objects that can change in ways that cannot be determined by the compiler. Objects declared as volatile are omitted from optimization because their values can be changed by code outside the scope of current code at any time.

How do you use volatile?

Volatile is used in C programming when we need to go and read the value stored by the pointer at the address pointed by the pointer. If you need to change anything in your code that is out of compiler reach you can use this volatile keyword before the variable for which you want to change the value.

Is volatile safe?

Volatile variable is not thread safe. If multiple threads try to write on a volatile variable, then Race condition occurs. Each thread has a separate m/m space known as working m/m , this holds the value of diff. variables for performing operations.


2 Answers

From what I understand it always appears as if the cache has been flushed after write, and always appears as if reads are conducted straight from memory on read. The effect is that a Thread will always see the results of writes from another Thread and (according to the Java Memory Model) never a cached value. The actual implementation and CPU instructions will vary from one architecture to another however.

It doesn't guarantee correctness if you increment the variable in more than one thread, or check its value and take some action since obviously there is no actual synchronization. You can generally only guarantee correct execution if there is only just Thread writing to the variable and others are all reading.

Also note that a 64 bit NON-volatile variable can be read/written as two 32 bit variables, so the 32 bit variables are atomic on write but the 64 bit ones aren't. One half can be written before another - so the value read could be nether the old or the new value.

This is quite a helpful page from my bookmarks:

http://www.cs.umd.edu/~pugh/java/memoryModel/

like image 188
gub Avatar answered Oct 24 '22 04:10

gub


Exactly what happens is processor-specific. Generally there are some form of memory barrier instructions. Flushing the entire cache would obviously be very expensive - there are cache coherency protocols in the hardware.

Also important, is that certain optimisations are not made across the field accesses. The compiler is important when considering multithreading, don't just think about the hardware.

like image 22
Tom Hawtin - tackline Avatar answered Oct 24 '22 04:10

Tom Hawtin - tackline