No, there is not. The additional power provided by AtomicReference is the compareAndSet() method and friends. If you do not need those methods, a volatile reference provides the same semantics as AtomicReference.
AtomicReference class provides operations on underlying object reference that can be read and written atomically, and also contains advanced atomic operations. AtomicReference supports atomic operations on underlying object reference variable.
The synchronized approach is a more general purpose mechanism; with the synchronized block you can group together multiple assignments much more easily, where with atomic references it's much more involved.
The volatile modifier is used to let the JVM know that a thread accessing the variable must always merge its own private copy of the variable with the master copy in the memory. Accessing a volatile variable synchronizes all the cached copied of the variables in the main memory.
Short answer is: No.
From the java.util.concurrent.atomic
package documentation. To quote:
The memory effects for accesses and updates of atomics generally follow the rules for volatiles:
get
has the memory effects of reading avolatile
variable.set
has the memory effects of writing (assigning) avolatile
variable.
By the way, that documentation is very good and everything is explained.
AtomicReference::lazySet
is a newer (Java 6+) operation introduced that has semantics unachievable through volatile
variables. See this post for more information.
No, there is not.
The additional power provided by AtomicReference is the compareAndSet() method and friends. If you do not need those methods, a volatile reference provides the same semantics as AtomicReference.set() and .get().
There are several differences and tradeoffs:
Using an AtomicReference
get/set has the same JMM semantics as a volatile field(as the javadoc states), but the AtomicReference
is a wrapper around a reference, so any access to the field involves a further pointer chase.
The memory footprint is multiplied (assuming a compressed OOPs environment, which is true for most VMs):
AtomicReference
= 4b + 16b (12b object header + 4b ref field)AtomicReference
offers a richer API than a volatile reference. You can regain the API for the volatile reference by using an AtomicFieldUpdater
, or with Java 9 a VarHandle
. You can also reach straight for sun.misc.Unsafe
if you like running with scissors. AtomicReference
itself is implemented using Unsafe
.
So, when is it good to choose one over the other:
AtomicReference
/AtomicFieldUpdater
/Unsafe
where you tend to pay in readability and risk for your performance gain. If this not a sensitive area just go for AtomicReference
. Library writers typically use a mix of these methods depending on targeted JDKs, expected API restrictions, memory constraints and so on.JDK source code is one of the best ways to answers confusions like this. If you look at the code in AtomicReference, it uses a volatie variable for object storage.
private volatile V value;
So, obviously if you are going to just use get() and set() on AtomicReference it is like using a volatile variable. But as other readers commented, AtomicReference provides additional CAS semantics. So, first decide if you want CAS semantics or not, and if you do only then use AtomicReference.
AtomicReference
provides additional functionality which a plain volatile variable does not provide. As you have read the API Javadoc you will know this, but it also provides a lock which can be useful for some operations.
However, unless you need this additional functionality I suggest you use a plain volatile
field.
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