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
|
All cached variables synchronized on access?
|
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;}
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.
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