That means that if a variable is being updated I will not see the new values until the update is complete and I will not block, rather what I see is the last updated value
This is your source of confusion. What volatile does is make sure that reads and writes to that field are atomic - so no other threads could ever see a partially written value.
A non-atomic long field (which takes 2 memory addresses on a 32-bit machine) could be read incorrectly if a write operation was preempted after writing to the first address, and before writing to the second address.
Note that the atomicity of reads/writes to a field has nothing to do with updating the inner state of an HashMap
. Updating the inner state of an HashMap
entails multiple instructions, which are not atomic as a whole. That's why you'd use locks to synchronize access to the HashMap
.
Also, since read/write operations on references are always atomic, even if the field is not marked as volatile, there is no difference between a volatile and a non-volatile HashMap, regarding atomicity. In that case, all volatile does is give you acquire-release semantics. This means that, even though the processor and the compiler are still allowed to slightly reorder your instructions, no instructions may ever be moved above a volatile read or below a volatile write.