Showing posts with label volatile. Show all posts
Showing posts with label volatile. Show all posts

Wednesday, 1 June 2011

Myth : Volatile means atomic!!

Volatile means visibility but sometimes people confuse it with atomicity.
Consider the following code:
volatile int i = 0;

//Thread 1:
i++;

//Thread 2:
i--;


So is the above code thread-safe?
The answer to this lies on 2 things -
  • i++ and i-- 
    are not atomic operations. See here for atomic operations. Read the integer to local, increment local and write back integer to the volatile field i.
  • volatile only guarantees visibility between the threads
So above code can be read as :
//Thread 1:r1,r2 local values
r1 = i;
r2 = r1 + 1;
i = r2;

//Thread 2:
r3 = i;
r4 = r3 - 1;
i = r4;
So, if Threads 1 and 2 both read v and see the value 0, then Thread 1 will write 1 to it and Thread 2 will write -1 to it. You are not guaranteed to see the value 0!
So to make above code thread-safe, you should use java.util.concurrent.atomic classes, which allows to create object and allow atomic increment and decrement with support from hardware or processor level.

Monday, 30 May 2011

Difference between synchronized and volatile



The main differences between synchronized and volatile are:
  • a primitive variable may be declared volatile whereas synchronized cannot be applied on the primitive types, but on some object or method or class.
  • Lock - Volatile deals with visibility, so if one thread modifies some variable, it will be known to other thread, so unlike a synchronized block we will never hold on to any lock; This is the big difference as synchronized offers mutual exclusion while volatile don't.
  • Attempting to synchronize on a null object will throw a NullPointerException, while  this is fine with volatile.
  • As synchronized offers mutual exclusion, it offers atomicity as well. But volatile doesn't mean atomic. (click on the link to see why)
Thanks

Thursday, 26 May 2011

Volatile keyword in java

Understanding volatile in java
To understand volatile, first you have to understand a little something about the Java memory model.
  • Each thread in Java takes place in a separate memory space, I mean its personal stack, but various threads share memory among them.
  • You need to use special mechanisms to guarantee that communication happens between these threads, as you would on a message passing system.
  • Memory writes that happen in one thread can "leak through" and be seen by another thread, but this is by no means guaranteed. Without explicit communication (i.e. using locks on the shared data), you can't guarantee which writes get seen by other threads, or even the order in which they get seen.
The Java volatile modifier guarantees that communication happens between threads. When one thread writes to a volatile variable, and another thread sees that write, the first thread is telling the second about all of the contents of memory up until it performed the write to that volatile variable. So if a variable is declared as volatile then is guaranteed that any thread which reads the field will see the most recently written value.

What is happens-before relation?
volatile’s job is to guarantee “happens-before” behavior. This means three things:
  1. Write operations are executed before read operations.
  2. Compilers are not allowed to re-order accesses to the field.
  3. Caches must be flushed before reading the field
Note
The keyword volatile will not perform any mutual exclusive lock on the variable. Most recent value is ensured because it ignores caching. So if a variable is declared volatile, it takes the value from the main memory, rather than cache and delivers the recent value or latest value.

As of Java 5 write access to a volatile variable will also update non-volatile variables which were modified by the same thread. This can also be used to update values within a reference variable, e.g. for a volatile variable person. In this case you must use a temporary variable person and use the setter to initialize the variable and then assign the temporary variable to the final variable. This will then make the address changes of this variable and the values visible to other threads.

Difference between volatile in old and new Java Memory Model
Pre-java 5, volatile had different meaning, but java developers changed its meaning. Lets look at the change:
Old java volatile New java volatile
A volatile variable cannot be cached. (same)
A volatile variable cannot be reordered with another variable but may be reordered with volatile variable. A volatile variable cannot be reordered. (notice the change)
Volatile observes happens-before-relationship.
See -