Volatile variable can be used as an alternative way of achieving synchronization in Java
in some cases, like Visibility. with volatile variable its guaranteed that all reader thread will see updated value of volatile variable once write operation completed, without volatile keyword different reader thread may see different values. An access to a volatile variable in Java never has chance to block, since we are only doing a simple read or write, so unlike a synchronized block we will never hold on to any lock or wait for any lock. volatile has semantics for memory visibility. Basically, the value of a volatile field becomes visible to all readers (other threads in particular) after a write operation completes on it. Without volatile, readers could see some non-updated value.
volatile is used to indicate that a variable's value will be modified by different threads Declaring a volatile Java variable means: The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory"; Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself. a primitive variable may be declared volatile (whereas you can't synchronize on a primitive with synchronized); an access to a volatile variable never has the potential to block: we're only ever doing a simple read or write, so unlike a synchronized block we will never hold on to any lock; because accessing a volatile variable never holds a lock, it is not suitable for cases where we want to read-update-write as an atomic operation (unless we're prepared to "miss an update"); a volatile variable that is an object reference may be null (because you're effectively synchronizing on the reference, not the actual object).
The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory". Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself.
Characteristic Synchronized Volatile Type of variable Object Object or primitive Null allowed? No Yes Can block? Yes No All cached variables synchronized on access? Yes From Java 5 onwards When synchronization happens When you explicitly enter/exit a synchronizedblock Whenever a volatile variable is accessed. Can be used to combined several operations into an atomic operation? Yes Pre-Java 5, no. Atomic get- set of volatiles possible in Java 5.
When to use Volatile? A "simple flag" accessed by multiple threads The most typical case is where: you write a variable, such as a flag, in one thread; you check that variable in another thread;
Volatile is useful in Stopping the Threads public class Foo extends Thread { private volatile boolean close = false; public void run() { while(!close) { // do work } } public void close() { close = true; // interrupt here if needed } }
Double check single ton
Public class SingleTon {
Public static volatile singletonintance ;
Public static SingleTon getinstance() { If (singletonintance == null) { Synchronized(SingleTon.class) { If (singletonintance == null) { Singletonintance = new SingleTon();
} }
}
Return Singletonintance
} }
One More Change Maker and Listner
public class VolatileTest {
private static volatile int MY_INT = 0;
public static void main(String[] args) throws InterruptedException { new ChangeListener().start(); System.out.println("Waiting two seconds so the JIT will probably optimize ChangeListener"); Thread.sleep(2000);
new ChangeMaker().start(); }
static class ChangeListener extends Thread { @Override public void run() { int local_value = MY_INT; while ( local_value < 5){ if( local_value!= MY_INT){ System.out.println("Got Change for MY_INT : "+ MY_INT); local_value= MY_INT; } } } }
static class ChangeMaker extends Thread{ @Override public void run() {
With the volatile keyword the output is : Incrementing MY_INT to 1 Got Change for MY_INT : 1 Incrementing MY_INT to 2 Got Change for MY_INT : 2 Incrementing MY_INT to 3 Got Change for MY_INT : 3 Incrementing MY_INT to 4 Got Change for MY_INT : 4 Incrementing MY_INT to 5 Got Change for MY_INT : 5
Without the volatile keyword the output is : Incrementing MY_INT to 1 Incrementing MY_INT to 2 Incrementing MY_INT to 3 Incrementing MY_INT to 4 Incrementing MY_INT to 5 .....And the change listener loop infinitely..
The last point above outlaws cases such as x++ or x += 7, because this actually involves reading the current value, incrementing it, then setting the new value