If you’re working with Spring, check out "REST With Spring":

>> CHECK OUT THE COURSE

1. Overview

In this quick article, we’ll focus on a foundational but often misunderstood concept in the Java language – the volatile keyword.

In Java, each thread has a separate memory space known as working memory; this holds the values of different variables used for performing operations. After performing an operation, thread copies the updated value of the variable to the main memory, and from there other threads can read the latest value.

Simply put, the volatile keyword marks a variable to always go to main memory, for both reads and writes, in the case of multiple threads accessing it.

2. When to Use volatile

In the situations where the next value of the variable is dependent on the previous value, there is a chance that multiple threads reading and writing the variable may go out of sync, due to a time gap between the reading and writing back to the main memory.

This can be illustrated by a simple example:

public class SharedObject {
    private volatile int count = 0;
   
    public void increamentCount() {      
        count++;
    }
    public int getCount() {
        return count;
    }
}

With no synchronization here, a typical race condition can occur. Basically, with an execution gap between incrementing and writing it to main memory, other threads might see a value of 0, and try to write it to main memory.

The race condition can of course also be avoided with the use of the Java provided atomic data types like AtomicInt or AtomicLong.

3. Volatile and Thread Synchronization

For all the multithreaded applications, we need to ensure a couple of rules for a consistent behavior:

  • Mutual Exclusion – only one thread executes a critical section at a time
  • Visibility – changes made by one thread to the shared data, are visible to other threads to maintain a data consistency

Synchronized methods and blocks provide both of the above properties, at the cost of performance of the application.

Volatile is quite a useful primitive because it can help ensure the visibility aspect of the data change, without, of course, providing the mutual exclusion. Thus, it’s useful in the places where we are ok with multiple threads are executing a block of code in parallel but we need to ensure the visibility property.

4. Happens-Before Guarantee

Starting with Java 5, the volatile keyword also provides additional capabilities which ensure that values of all the variables including non-volatile variables are written to the main memory along with the Volatile write operation.

This is called Happens-Before, as it gives a visibility of all variables to another reading thread. Also, JVM doesn’t reorder the reading and writing instructions of volatile variables.

Let’s have a look at the example:

Thread 1
    object.aNonValitileVariable = 1;
    object.aVolatileVariable = 100; // volatile write

Thread 2:
    int aNonValitileVariable = object.aNonValitileVariable;
    int aVolatileVariable =  object.aVolatileVariable;

In this case, when Thread 1 has written the value of aVolatileVariable then the value of aNonValitileVariable is also written to the main memory. And even though it’s not a volatile variable, it is exhibiting a volatile behavior.

By making use of these semantics, we can define only a few of the variables in our class as volatile and optimize the visibility guarantee.

5. Conclusion

In this tutorial, we’ve explored more about the volatile keyword and its capabilities, as well as the improvements made to it starting with Java 5.

As always, the code examples can be found over on GitHub.

The new Certification Class of "REST With Spring" is finally out:

>> CHECK OUT THE COURSE

Sort by:   newest | oldest | most voted
salman
Guest

Why non volatile variable also written in main memory ?

Grzegorz Piwowarek
Editor

It’s the feature introduced in JDK 5 to ensure proper ordering of operations which is supposed to prevent memory-inconsistency problems

salman
Guest

So if there is no volatile variable in particular thread, it will not directly written in main memory right ?

Grzegorz Piwowarek
Editor

You mean “class”? Yes, then will not cross the memory barrier then

Chandan
Guest

When a volatile variable is written, does all non-volatile variable(including variables of other classes) are written to main? Or only variable of that particular class(where volatile is defined) are updated?

Grzegorz Piwowarek
Editor

No, if it was the case the whole application would suffer a performance impact because all reads/writes would need to cross the memory barrier.

Only variable of that particular class will be written to the main memory, however, it might also enforce similar behaviour in other fields of particular class (as described in section 4 )

Franklin
Guest

I can tell that the author is a good student of legendary Brian Goetz :o)

wpDiscuz