1

After Googling a lot, I found multiple definitions for volatile keyword.

Concept 1:

Some Website says, it is thread safe, as thread acts on the main memory where volatile keyword is stored and modifies it without pulling it to thread stack space.

Concept 2:

Some says, it is not thread safe, as it causes Thread race condition. As , thread pulls volatile variable to stack space , modifies it and immediately puts it back to main memory. But, in between another thread can come and act upon the volatile variable and takes action. So, this way, some value gets missing.

Which concept is correct?

xingbin
  • 27,410
  • 9
  • 53
  • 103
  • Both can be correct, depending on how exactly the volatile variable is used. – yole Oct 31 '18 at 12:56
  • Since you're asking about Java, be sure that you're reading Java-specific explanations. The `volatile` keyword has different meanings in different programming languages. – Solomon Slow Oct 31 '18 at 13:50

5 Answers5

7

volatile is neither thread-safe nor non-thread-safe on its own.

volatile guarantees atomicity for a single field, and so it can be used for single thread-safe reads or single thread-safe writes.

However, if you want to perform a thread-safe operation consisting of a read followed by a write (understood as a whole), volatile alone does not provide thread safety here because volatile guarantees atomicity only to single operations (either read or write).

To sum up:

  • if you have a field and you want to make sure that if one thread writes to it, other threads can immediately read the written value - volatile is enough (without volatile, other threads may never even see the written value)
  • if you have a field that you need to first read and only then write (based on the value you just read so no operations on this value may happen in between), volatile is not enough; instead, you can use:
Tomasz Linkowski
  • 4,386
  • 23
  • 38
3

This IBM article sums this up pretty nicely:

Volatile variables share the visibility features of synchronized, but none of the atomicity features. This means that threads will automatically see the most up-to-date value for volatile variables. They can be used to provide thread safety, but only in a very restricted set of cases: those that do not impose constraints between multiple variables or between a variable's current value and its future values. So volatile alone is not strong enough to implement a counter, a mutex, or any class that has invariants that relate multiple variables (such as "start <=end").

Source: https://www.ibm.com/developerworks/java/library/j-jtp06197/

Somehow related StackOverflow question: Do you ever use the volatile keyword in Java?

maio290
  • 6,440
  • 1
  • 21
  • 38
3

Here is , what I understood after thorough Googling:

• Volatile keyword is used to avoid the local copies of a variable inside threads. All threads will access the volatile variable from main memory , updates it and immediately put it back in main m/m.

From ibm.com: All reads and writes would be made directly to main m/m instead of to registers or local processor cache.

• 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. After performing an operation , thread copies the updated value of the variable to main m/m and from there other threads can read the latest value. But, if the variable is non-volatile, then new value may not be flushed immediately to main m/m. And other threads may not read the updated value.

• Synchronization provides both Mutual Exclusion and Visibility. But volatile provides visibility only.

2

The concept 1 is easy to understand, but it is incorrect. volatile is some kind of synchronization specification provided by JMM, is is not about implemention. Also, it can not gurantee thread safe in all circumstances.

Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable.

This means that changes to a volatile variable are always visible to other threads. What's more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.

Thread safe usage:

1. int value = 1;
2. thread1 executes: value = 2;
3. when thread2 reads value, it must be 2

Thread unsafe usage:

1. int value = 1;
2. thread1 executes: value++;
3. when thread2 reads value, it could be 1 or 2, because value++ is not atomic.
xingbin
  • 27,410
  • 9
  • 53
  • 103
0

only using volatile does not make a critical section a thread safe. simply it help us in two ways.

  1. Thread can have it is own copy of memory location values (probably loaded to registry or cache). when volatile variable is accessed it will always read from main memory.

  2. java compiler does not reorder usage of these variables (specially from synchronization scope).

that means, to write a thread safe code we might have to use volatile, but just using volatile does not make any good.

hunter
  • 3,963
  • 1
  • 16
  • 19