سؤال

I don´t get the difference between these two:

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

vs.

AtomicInteger atomicInteger = new AtomicInteger(1);

Can someone generally say when to use AtomicReference? Hope someone can help me. Thanks.

هل كانت مفيدة؟

المحلول

A very important difference is that the methods compareAndSet and weakCompareAndSet have different semantics for AtomicReference<Integer> than they do for AtomicInteger. This is because with AtomicReference<Integer>, those methods use == for comparing and two Integer objects can be equal without being ==. With AtomicInteger, the comparison is of the integer value equality, not reference identity.

As others have pointed out, AtomicInteger has additional features not available with AtomicReference<Integer>. Also, AtomicInteger extends Number, so it inherits all the Number methods (doubleValue(), etc.) and can be used whenever a Number is expected.

نصائح أخرى

Not much difference if you are using just set(...) and get() but the AtomicInteger has some other methods such as incrementAndGet() which only work for integers.

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

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 AtomicReference<V>.

AtomicInteger is a specialized version that contains integers. It is more efficient (no unnecessary boxing), and has useful methods like incrementAndGet().

As pointed out by others, AtomicReference<Integer> uses == to compare objects. Therefore,compareAndSet(expect, update) will update your initial reference only if expect equals to the object stored in your your atomic reference using ==.

It can lead to some tricky bugs if you use AtomicReference for numeric types, i.e. Integer or Long. Please note that static constructors of those classes (for example, Integer.valueOf(int value)) return internally cached objects for small values. In other words, two different calls to Integer.valueOf(5) returns the same instance of Integer. It is safe, as the classes are immutable. In the result, if you use AtomicReference<Integer> whereas you should really be using AtomicInteger, it may work fine for these small numbers, because == may actually compare the same objects. It gets worse only when you begin to handle with higher values at some point.

Summing up, using AtomicInteger is much safer for numeric operations :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top