I am not able to understand the purpose of writing the sequence of operations inside a infinite for loop.
The purpose of this code is to ensure that the volatile
field gets updated appropriately without the overhead of a synchronized
lock. Unless there are a large number of threads all competing to update this same field, this will most likely spin a very few times to accomplish this.
The volatile
keyword provides visibility and memory synchronization guarantees but does not in itself ensure atomic operations with multiple operations (test and set). If you are testing and then setting a volatile
field there are race-conditions if multiple threads are trying to perform the same operation at the same time. In this case, if multiple threads are trying to increment the AtomicInteger
at the same time, you might miss one of the increments. The concurrent code here uses the spin loop and the compareAndSet
underlying methods to make sure that the volatile int
is only updated to 4 (for example) if it still is equal to 3.
- t1 gets the atomic-int and it is 0.
- t2 gets the atomic-int and it is 0.
- t1 adds 1 to it
- t1 atomically tests to make sure it is 0, it is, and stores 1.
- t2 adds 1 to it
- t2 atomically tests to make sure it is 0, it is not, so it has to spin and try again.
- t2 gets the atomic-int and it is 1.
- t2 adds 1 to it
- t2 atomically tests to make sure it is 1, it is, and stores 2.
Does it serve any special purpose in Java Memory Model (JMM).
No, it serves the purpose of the class and method definitions and uses the JMM and the language definitions around volatile
to achieve its purpose. The JMM defines what the language does with the synchronized
, volatile
, and other keywords and how multiple threads interact with cached and central memory. This is mostly about native code interactions with operating system and hardware and is rarely, if ever, about Java code.
It is the compareAndSet(...)
method which gets closer to the JMM by calling into the Unsafe
class which is mostly native methods with some wrappers:
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}