What is the difference between AtomicReference <Integer> and AtomicInteger?

I do not understand the difference between the two:

AtomicReference<Integer> atomicReference = new AtomicReference<>(1); 

vs.

 AtomicInteger atomicInteger = new AtomicInteger(1); 

Can anyone even tell when to use AtomicReference? Hope someone can help me. Thanks.

+6
source share
4 answers

It is very important to distinguish that the compareAndSet and weakCompareAndSet have different semantics for AtomicReference<Integer> than for AtomicInteger . This is due to the fact that with AtomicReferece<Integer> these methods use == for comparison, and two Integer objects can be equal without == . Using AtomicInteger comparison has an integer value, not a link identifier.

As others have noted, AtomicInteger has additional features not available with AtomicReference<Integer> . In addition, AtomicInteger extends Number , so it inherits all Number methods ( doubleValue() , etc.) and can be used whenever waiting for Number .

+9
source

Not much difference if you only use set(...) and get() , but AtomicInteger has some other methods like incrementAndGet() that only work for integers.

AtomicReference wraps a volatile Object , and AtomicInteger wraps a volatile int , so it can execute integer specific methods, including increment, decrement, and add methods. AtomicInteger also extends Number , which means it supports the doubleValue() , longValue() , etc. methods.

+8
source

AtomicReference is a generic class that can refer to arbitrary types.
If you want to use an instance of your own class atomically, you need an AtomicReference<V> .

AtomicInteger is a specialized version containing integers. It is more efficient (without extra boxing) and has useful methods such as incrementAndGet() .

+6
source

As pointed out by others, AtomicReference<Integer> uses == to compare objects. Therefore, compareAndSet(expect, update) update your source link if expect matches the object stored in your atomic link using ==.

This can lead to some complicated errors if you use AtomicReference for numeric types, i.e. Integer or Long . Note that the static constructors of these classes (e.g. Integer.valueOf(int value) ) return internal cached objects for small values. In other words, two different calls to Integer.valueOf(5) return the same Integer instance. This is safe because classes are immutable. As a result, if you use AtomicReference<Integer> , while you really should use AtomicInteger , it can work fine for these small numbers, because == can actually compare the same objects. This only gets worse when you start to process higher values ​​at some point.

To summarize, using AtomicInteger much safer for numerical operations :)

+2
source

All Articles