What is volatile variable and where to use this?
Volatile keyword is used to indicate that a variable's value will be
modified by different threads running concurrently. If we are declaring a
variable as volatile means: -
We are providing an indicator to Java compiler and Thread that don’t
cache value of this variable and always read it from main memory. Java volatile
keyword also prevents from reordering of code and gives guarantees of visibility.
With the use of volatile keyword, in multithreaded environment all the
reader thread will see the updated value of volatile variable. (Note: -
without volatile keyword, reader threads will get different-different values)
When
multiple threads using the same variable, each thread will have its own copy of
the local cache for that variable. So, when it’s updating the value, it is
actually updated in the local cache not in the main memory.
The other
thread which is using the same variable doesn’t know anything about the values
changed by another thread. So, to overcome from this problem we are using the
volatile keyword and indicating to the threads that don’t cache value of this
variable and always read it from main memory.
In Java, with
the use of volatile keyword on variables reduces the risk of memory inconsistency
errors, because any write to a volatile variable in Java establishes a
happens-before relationship with subsequent reads of that same variable.
Difference
between volatile and synchronized in java
- synchronized modifies code blocks and methods where as volatile keyword is used as a modifier with variable.
- In Java, volatile keyword only synchronizes the value of one variable between thread memory and main memory while synchronized keyword synchronizes the value of all variable between thread memory and main memory
-
· volatile works faster as compare to synchronized because synchronized affects a lot on performance due to obtain and release of lock.· Obtaining and releasing lock is not required by volatile but it is necessary for synchronized.
Note: - With the use of java, in some cases we can use volatile keyword instead
of synchronized because it will save performance overhead which comes with the use of
synchronization. But volatile keyword is not the replacement or
alternative of synchronized block or method.
What is happens – before relationship?
The key to avoiding memory inconsistency errors is understanding the happens-before
relationship. This relationship is simply a guarantee that memory writes by one
specific statement are visible to another specific statement.
int counter = 0;
The counter
field is shared between two threads A and B. Suppose thread A increments counter:
counter++;
Then,
shortly thread B prints out counter:
System.out.println(counter);
If the two
statements had been executed in the same thread, it would be safe to assume
that the value printed out would be "1". But if the two statements
are executed in separate threads, the value printed out might well be "0",
because there's no guarantee that thread A's change to counter will be visible
to thread B — unless the programmer has established a happens-before
relationship between these two statements. There are several actions that
create happens-before relationships. One of them is synchronization
What is Monitor in java?
Java's
monitor supports two kinds of thread synchronization: mutual exclusion and cooperation.
Mutual exclusion, which is supported in the JVM via object
locks, enables multiple threads to independently work on shared data without
interfering with each other. Cooperation, which is supported in the JVM via the wait() and notify() methods of class Object, enables threads
to work together towards a common goal.
A monitor
is just like a building that contains one type of special room that can be occupied by only
one thread at a time. The room usually contains some data. From the time a
thread enters in this room to the time it leaves, it has exclusive access to any
data in that room. Entering the monitor building is called "entering the
monitor", Entering the special room inside the building is called
"acquiring the monitor", Occupying the room is called "owning
the monitor", and leaving the room is called "releasing the
monitor", Leaving the entire building is called "exiting the
monitor".
Demo example of volatile variable
package com.gaurav.multithreads;
public class UseOfVolatileExampleDemo extends Thread {
private volatile int tempVal;
public void run() {
System.out.println("*****run method called*****");
for (int i = 1; i <= 7; i++) {
try {
System.out.println(getName() + " Iteration Number :- " + i);
synchronized (UseOfVolatileExampleDemo.class) {
if (getName().equals("Thread First # ")) {
tempVal = tempVal + 100;
System.out.println("Test Value after "+ i + " iteration :- " + tempVal);
}
}
if (getName().equals("Thread Second # ")) {
tempVal = tempVal + 100;
System.out.println("Test Value after "+ i + " iteration :- " + tempVal);
}
Thread.sleep(3000);//For 3s halt
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
public UseOfVolatileExampleDemo(String str) {
super(str);
}
public static void main(String args[]) {
UseOfVolatileExampleDemo uved = new UseOfVolatileExampleDemo("Thread First # ");
uved.start();
UseOfVolatileExampleDemo uved1 = new UseOfVolatileExampleDemo("Thread Second # ");
uved1.start();
}
}
public class UseOfVolatileExampleDemo extends Thread {
private volatile int tempVal;
public void run() {
System.out.println("*****run method called*****");
for (int i = 1; i <= 7; i++) {
try {
System.out.println(getName() + " Iteration Number :- " + i);
synchronized (UseOfVolatileExampleDemo.class) {
if (getName().equals("Thread First # ")) {
tempVal = tempVal + 100;
System.out.println("Test Value after "+ i + " iteration :- " + tempVal);
}
}
if (getName().equals("Thread Second # ")) {
tempVal = tempVal + 100;
System.out.println("Test Value after "+ i + " iteration :- " + tempVal);
}
Thread.sleep(3000);//For 3s halt
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
public UseOfVolatileExampleDemo(String str) {
super(str);
}
public static void main(String args[]) {
UseOfVolatileExampleDemo uved = new UseOfVolatileExampleDemo("Thread First # ");
uved.start();
UseOfVolatileExampleDemo uved1 = new UseOfVolatileExampleDemo("Thread Second # ");
uved1.start();
}
}
Result:-
Hello friend... The output of the program will be the same regardless of the variable being volatile or non volatile. For corrrect demonstration, the worker threads have to access the same volatile variable and this is not the case in the above example because both the threads are working on different "tempVal" variables.
ReplyDeleteΤου μουνιού σου μία τρίχα, μου δυνάμωσε το βήχα.
ReplyDelete