Playing with Atomicity and the volatile modifier
During the course of some reading that I am doing for Whirlycache, I started to wonder about the effect that Java’s
volatile modifier really has. So I wrote a test to find out.
Basically, it’s just 32 threads running in a loop of 10 million iterations doing auto-increments on two
long fields, one of which is marked as
volatile. The results consistently look something like this:
Number of loops: 320000000 Non-volatile long: 134162630 Volatile long: 29800659
We can learn two things here: Java’s autoincrement operator is indeed not atomic since it involves a read and a write (but that’s not real news) and
volatile made about 4.5 times more of a difference than I thought it would in this test.
The surprising thing was that the volatile long value was much less than the non-volatile long. I expected the opposite, but it turns out that the fact that each thread has to read the contents of the volatile modifier out of main memory causes each operation’s result to be clobbered by another thread concurrently writing to the same field. When the field isn’t marked as volatile, each thread maintains a local copy of the field in main memory and actually has a chance of doing some work on it before writing a modified copy of the field back into the main memory.
I also found a very good article today on IBM developerworks about Java synchronization.