Volatile keyword in Java
Multiple threads can change a variable's value by using the volatile keyword. Making classes thread-safe is another application for it. It indicates that using a method or an instance of a class by several threads is not problematic. Both primitive types and objects are compatible with the volatile keyword. The volatile keyword always reads the variable's value from the main memory rather than caching it. Classes and methods cannot be combined with the volatile keyword.
Suppose there are two threads for a class. If the two threads are run on two different processors, and one thread modifies the variable’s value, it does not change in one line. It affects the code usability and creates inconsistency in data.
Syntax
class Test
{
static volatile int var =13;
// volatile keyword make changes to the variable if change occurs in any of the thread
}
Advantages of Volatile Keyword
- If we want to declare long and double variables automatically, we can use the volatile keyword.
- Read and write operations on volatile keywords that are atomic.
- Memory consistency error is reduced.
- Object reference of volatile keyword is null
- Other threads can see volatile keywords
- If you do not share the variables between two threads, then it is not required to use the volatile keyword.
- Volatile keyword memory is read from the main memory
Volatile vs Synchronised
Volatile | Synchronised |
Volatile is applicable to only keywords | Synchronised is applicable only to methods. |
Mutual exclusion states that only one thread or process can run a vital part of code at once. | The synchronised keyword in Java ensures visibility and mutual exclusion. |
Other threads are able to see changes made to shared data by one thread. | Only one thread can enter the block and its modifications will be reflected in the main memory if we synchronise the blocks of threads that modify the value of the shared variable. All other threads will be blocked and put to sleep if they attempt to enter the block concurrently. |
Use of Volatile Keyword
public class Volatile
{
private final static int no_of_threads = 2 ;
public static void main ( String [ ] args ) throws InterruptedException
{
VolatileData vd = new VolatileData ( ) ; // ----volatile_data class ovject is created - - - - -
Thread [ ] t = new Thread [ no_of_threads ] ; // Thread array is created with name t
for ( int i = 0 ; i < no_of_threads ; ++i )
t [ i ] = new ThreadVolatile ( vd ) ;
for ( int i = 0 ; i < no_of_threads ; ++i )
t [ i ] . start ( ) ; // -- all reader threads are started ---
for ( int i = 0 ; i < no_of_threads; ++i)
t [ i ] . join ( ) ; // --all threads are in wait state--
}
}
VolatileData.java
// Class with the name VolatileData is created to store the volatile variable data
public class VolatileData
{
private volatile int counter1 = 0 ;
public int getCounter1 ( )
{
return counter1 ;
}
public void increaseCounter1 ( )
{
++counter1 ; // counter variable value is increased by one
}
}
ThreadVolatile.java
// class with the name thread_volatile is created and using inheritance extending the properties of the thread class
public class ThreadVolatile extends Thread
{
// A final keyword is declared as volatile
private final VolatileData data1 ;
public ThreadVolatile ( VolatileData data1 )
{
this.data1 = data1 ;
}
@Override
// run method is used to start the threads
public void run ( )
{
int old_value = data1 . getCounter1 ( ) ;
System . out . println ( " [ Thread " + Thread . currentThread ( ) . getId ( ) + " ] : Old value = =" + old_value ) ;
data1 . increaseCounter1 ( ) ;
int new_value = data1 . getCounter1 ( ) ;
// Printing the thread
System . out . println ( " [ Thread is " + Thread . currentThread ( ) . getId ( ) + " ] : New value = " + new_value ) ;
}
}
Output
