В чем разница между AtomicReference<Integer> и AtomicInteger?

Я не понимаю разницы между этими двумя:

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

против

AtomicInteger atomicInteger = new AtomicInteger(1);

Может кто-нибудь вообще сказать, когда использовать AtomicReference? Надеюсь, кто-нибудь может мне помочь. Благодарю.

4 ответа

Решение

Очень важным отличием является то, что методы compareAndSet а также weakCompareAndSet имеют различную семантику для AtomicReference<Integer> чем они делают для AtomicInteger, Это потому что с AtomicReferece<Integer>эти методы используют == для сравнения и два Integer объекты могут быть равны, не будучи ==, С AtomicInteger, сравнение имеет целочисленное равенство значений, а не ссылочную идентичность.

Как уже отмечали другие, AtomicInteger имеет дополнительные функции, недоступные с AtomicReference<Integer>, Также, AtomicInteger продолжается Numberтак что наследует все Number методы (doubleValue()и т. д.) и может использоваться всякий раз, когда Number ожидается.

Не большая разница, если вы используете только set(...) а также get() но AtomicInteger имеет некоторые другие методы, такие как incrementAndGet() которые работают только для целых чисел.

AtomicReference оборачивает volatile Object в то время как AtomicInteger оборачивает volatile int поэтому он может выполнять целочисленные методы, включая методы увеличения, уменьшения и добавления. AtomicInteger также расширяется Number что означает, что он поддерживает doubleValue(), longValue()и др. методы.

AtomicReference является универсальным классом, который может ссылаться на произвольные типы.
Если вы хотите использовать экземпляр вашего собственного класса атомарно, вам нужно AtomicReference<V>,

AtomicInteger специализированная версия, которая содержит целые числа Это более эффективно (без ненужного бокса), и имеет полезные методы, такие как incrementAndGet(),

Как отмечают другие, AtomicReference<Integer> использует == для сравнения объектов. Следовательно,compareAndSet(expect, update) обновит вашу первоначальную ссылку, только если expect равно объекту, сохраненному в вашей атомарной ссылке с использованием ==.

Это может привести к некоторым хитрым ошибкам, если вы используете AtomicReference для числовых типов, т.е. Integer или же Long, Обратите внимание, что статические конструкторы этих классов (например, Integer.valueOf(int value)) возвращать внутренне кэшированные объекты для небольших значений. Другими словами, два разных вызова Integer.valueOf(5) возвращает тот же экземпляр Integer, Это безопасно, так как классы неизменны. В результате, если вы используете AtomicReference<Integer> в то время как вы действительно должны использовать AtomicInteger, это может хорошо работать для этих небольших чисел, потому что == может фактически сравнивать одни и те же объекты. Хуже только тогда, когда вы начинаете работать с более высокими значениями в какой-то момент.

Подводя итоги, используя AtomicInteger гораздо безопаснее для числовых операций:)

Другие вопросы по тегам