Tuesday, July 4, 2017

Synchronized & Volatile in Java.

In computing world, a resource can be accessed from different threads concurrently. This can lead to inconsistency and data corruption. A thread ThreadA accesses a resource and modifies it. In the meantime, the thread ThreadB starts accessing the same resource. Data may get corrupted since it is concurrently being modified. 

Example to show, how multi-threading works. 

Synchronized Modifier
Let's start with a sample example with out the synchronized block.



Following program generated different outputs, because the same method printCount is accessed by two threads and called. 
Output-1:


Output-2: 
 Output-3:

Both modifiers deal with multi-threading and protection of code sections from threads accesses. 


The synchronized modifier can be applied to a statement block or a method. Synchronized provides protection by ensuring that a crucial section of the code is never executed concurrently by two different threads, ensuring data consistency. Let´s apply the modifier synchronized to the previous example to see how it would be protected:




After adding the Synchronized block in the code, following is the output.



Volatile Modifier

Essentially, 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.
We say "acts as though" in the second point, because to the programmer at least (and probably in most JVM implementations) there is no actual lock object involved. Here is how synchronized and volatile compare:
Difference between synchronized and volatile

Characteristic
Synchronized
Volatile
Type of variable
Object
Object or primitive
Null allowed?
No
Yes
Can block?
Yes
No
Yes
From Java 5 onwards
When synchronization happens
When you explicitly enter/exit a synchronized block
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.

In other words, the main differences between synchronized and volatile are:
  • 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).
Attempting to synchronize on a null object will throw a NullPointerException.


int firstVariable;
int getFirstVariable() {return firstVariable;}
volatile int secondVariable;
int getSecondVariable() {return secondVariable;}
int thirdVariable;
synchronized int getThirdVariable() {return thirdVariable;}



The first method is non-protected. A thread T1 will access the method, create its own local copy of firstVariable, and play with it. In the meantime, T2 and T3 can also access firstVariable and modify its value. T1, T2, and T3 will have their own values of firstVariable, which might not be the same and that have not been copied to the Main memory of Java, where the real results are held.

getSecondVariable(), on the other hand, accesses a variable that has been declared as volatile. That means, each thread is still able to access the method or block since it has not been protected with synchronized, but they will all access the same variable from the main memory, and will not create their own local copy. Each thread will be accessing the same value.

And as we can imagine from the previous examples, getThirdVariable() will only be accessed from one thread at a time. That ensures that the variable will remained synchronized throughout all of the threads executions.





Ref:
http://www.javamex.com/tutorials/java_final_performance_vs_non_final.shtml
http://javarevisited.blogspot.in/2011/06/volatile-keyword-java-example-tutorial.html
https://stackoverflow.com/questions/3519664/difference-between-volatile-and-synchronized-in-java






0 comments:

Post a Comment