What does it mean for a reference to be assigned atomically in Java?
So what could have been wrong if reference assignment was not atomic in Java?
AtomicReference refers to an object reference. This reference is a volatile member variable in the AtomicReference instance as below. private volatile V value; get() simply returns the latest value of the variable (as volatiles do in a "happens before" manner).
AtomicReference supports atomic operations on underlying object reference variable. It have get and set methods that work like reads and writes on volatile variables. That is, a set has a happens-before relationship with any subsequent get on the same variable.
First of all, reference assignment is atomic because the specification says so. Besides that, there is no obstacle for JVM implementors to fulfill this constraint, as 64 Bit references are usually only used on 64 Bit architectures, where atomic 64 Bit assignment comes for free.
Generally, you can summarize atomic as "one at a time". For example, when accessing or mutating a property is atomic, it means that only one read or write operation can be performed at a time. If you have a program that reads a property atomically, this means that the property cannot change during this read operation.
This means that you will not get the corrupted reference ever. Suppose that you have the following class:
class MyClass {
Object obj = null;
}
In memory obj
is a null pointer, usually it's an integer number like 0x00000000
. Then suppose that in one thread you have an assignment:
this.obj = new Object();
Suppose that new Object()
is allocated in the memory and has the pointer like 0x12345678
. The reference atomicity ensures that when you check the obj
from another thread you will either have a null pointer (0x00000000
) or pointer to the new object (0x12345678
). But under no circumstances you can get the partially assigned reference (like 0x12340000
) which points to nowhere.
This might look obvious, but such problem may appear in low-level languages like C
depending on the CPU architecture and memory alignment. For example if your pointer is misaligned and crosses the cache line, it's possible that it will not be synchronously updated. In order to avoid such situation Java virtual machine always aligns pointers, so they never cross the cache line.
So were the Java references non-atomic, there would be a chance when dereferencing the reference written from another thread that you get not the object which was referenced before or after the assignment, but random memory location (which may lead to segmentation fault, corrupted heap or any other disaster).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With