Volatile is about a variable being visible across CPU Cores instead of being visible just in the cache line of a single Core
Each CPU Core in the hardware also has several cache lines at various distances from the CPU. These Cache lines are called Cache 1, Cache 2 and Cache 3.
Cache 1 is the nearest to the CPU and is the fastest, Cache 3 is the furthest from the CPU and is the slowest.
Variable values are cached in these cache lines.
CPU Core 1 <=> Cache Line 1 <=> Cache Line2 <=> Cache Line 3
CPU Core 3 <=> Cache Line 1 <=> Cache Line2 <=> Cache Line 3
So let us say there is a variable called "age" and there are 2 threads each running on a different CPU. Then there could be 2 copies of the age variable, one in a cache line of Core 1 and another in a cache line of Core 2.
This leads to a problem: It is possible that the same variable stored in cache lines of another CPU will be out of date with the value stored in a cache line of another core.
This is where the volatile keyword comes in. It moves the variable, so that instead of being stored only in multiple cache lines of multiple CPU Cores, it is also stored in main memory. The Cache line values are kept in sync with main memory.
This works fine when you do not care about atomicity. Let us explain what we mean by atomicity. Atomicity is like a transaction = it is saying that if you want to read a value and increment it - that this will all occur in the same transaction.
When you use the synchronized block or synchronized method, you can ensure that everything inside the synchronized block can only be performed by a single thread.
However blocking other threads doing any work with the synchronized block is not very performant. Therefore if you do not care about atomicity and are just happy that other threads read the latest value of the variable then use volatile for a variable instead of using the synchronized block.
If you do care about atomicity and want to do a read and write operation on the same variable in the same transaction then use the synchronized block or a lock. Note that a synchronized method is equivalent to a synchronized block in this discussion.
So what does a volatile keyword look like?:
private volatile int age;
Coding in such way as to understand the underlying hardware is called Mechanical Sympathy?
It is easy for us programmers to forget about hardware. Understanding the volatile keyword is called "Mechanical Sympathy". We should have an appreciation of the fundamentals of hardware.