A volatile write ensures that writes already performed do not appear after this write. However to ensure you see this you need to perform a volatile read first.
And consequently, we get the output by the reader thread as :
90,0
Correct. However if you perform your reads correctly you cannot get 0, 80
0, 0 - ok
90, 0 - ok
90, 80 - ok
0, 80 - breaks happens before.
However, your reads do not ensure happens before behaviour as it doesn't perform the volatile read first.
System.out.println(nonVolatileInt + ","+ volatileInt);
This reads the non-volatile fields first, so you could see an old version of the non-volatile field and a new version of the volatile field.
Note: in reality, you are highly unlikely to see a problem. This is because caches invalidate a whole cache line at a time and if these fields are in the same 64-byte block, you shouldn't see an inconsistency.
What is more likely to be a problem is this loop.
while (flag == false)
{}
The problem is; the JIT can see your thread nevers writes to flag
so it can inline the value. i.e. it never needs to read the value. This can result in an infinite loop.
http://vanillajava.blogspot.co.uk/2012/01/demonstrating-when-volatile-is-required.html