0

I just learned about the volatile keyword in Java.

Essentially it seems that if a variable is read from or written to in one CPU, then it is saved in that CPU's cache but not necessarily immediately written to memory.

In some cases I pass an object reference or primitive variable to another thread, but I have not used the volatile keyword because I didn't know about that keyword until now.

I believe that if a new Thread reads that variable for the first time there is no issue. However, if my understanding is correct, then if a second thread changes the variable, then the first Thread's CPU may have it in cache and report an out of date value. Is this a true understanding of the effects of omitting the volatile keyword?

Example:

  1. Thread A sets an object's variable value to "First".
  2. Thread B reads the value of that variable for the first time ever.
  3. Thread A changes the value to "Second".
  4. Thread B reads the value again shortly thereafter, but it still reports "First" because of CPU cache.

Is this the main consequence of omitting a volatile keyword when it is necessary? Thread reporting an out of date value?

Is my understanding here correct? Also I am open to any other suggestions about when it is NOT necessary to use the volatile keyword for a non-final variable that is accessed by another thread. I know when to use it, but I need to have a good understanding about when not to.

700 Software
  • 85,281
  • 83
  • 234
  • 341
  • don't use it )) – Leonidos Jan 13 '20 at 19:04
  • You got literal answers to your question, but what nobody else has said, is that `volatile` is a somewhat specialized, advanced topic. If you want to learn how to properly share variables between different threads in a Java program, then your first step should be to learn about `synchronized` blocks. https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html – Solomon Slow Jan 13 '20 at 22:54

2 Answers2

1

This is related to Java memory model, and how a thread can observe another thread. Within a single thread, the effects of operations executed in that thread is in the same sequence as they are written. If another thread is observing the variables modified by a thread, then the second thread may not see the modifications to those variables in the same order the first thread executes them. This can be because of caching, or compiler reordering of instructions.

Synchronized blocks include a memory barrier that writes cpu cache to memory, and the compiler knows not to reorganize the code to move things across a synchronize block boundary, so anything that happens before a synchronized block becomes visible to observing threads.

Access to volatile variables also include a memory barrier, so if a thread writes to a volatile variable, any thread reading that variable will read the latest value written to it.

So in general, modifications made to a non-volatile variable may not be visible to another thread until a synchronized block is entered. Modifications made to a volatile variable are visible immediately.

Burak Serdar
  • 46,455
  • 3
  • 40
  • 59
1

Volatile is used with variables that are shared between multiple threads.If you do not use volatile variable compiler can reorder the code, free to write in cache value of volatile variable instead of reading from the main memory.