Да, вы определенно можете. На самом деле, если вы посмотрите на исходный код AtomicInteger
, то увидите, что они делают именно это. AtomicInteger.get
просто возвращает value
, который является volatile int
(ссылка). Единственное реальное отличие от того, что вы сделали, и того, что они делают, заключается в том, что они используют CAS для приращения вместо синхронизации. На современном оборудовании CAS может устранить любые взаимные исключения; на старом оборудовании JVM поместит какой-то мьютекс вокруг приращения.
Изменчивые чтения выполняются примерно так же быстро, как и энергонезависимые, поэтому чтения будут довольно быстрыми.
Кроме того, гарантируется, что volatile
полей не порвутся: см. JLS 17.7, в котором указано, что volatile
long
и double
не подлежат разрыву слов. Таким образом, ваш код будет работать как с long
, так и с int
.
Как указывает Диего Френер, вы можете не увидеть результат приращения, если получите значение «прямо в тот момент», когда происходит приращение — вы увидите либо до, либо после. Конечно, если бы get
был синхронизирован, у вас было бы точно такое же поведение потока чтения - вы бы видели либо значение до приращения, либо значение после приращения. Так что это действительно то же самое в любом случае. Другими словами, не имеет смысла говорить, что вы не увидите значения в том виде, в каком оно происходит, если только вы не имеете в виду разрыв слов, который (а) вы не получите и (б) вам никогда не захочется.
person
yshavit
schedule
27.07.2012