2013-12-19 5 views
5

Сегодня я увидел этот класс утилиты для AtomicEnum, но мне интересно, возможно ли иметь атомное перечисление, почему оно не включено в стандартные библиотеки Java? На самом деле у меня так много сомнений в том, что он может быть действительно атомарным и если этот класс полезности работает.Можем ли мы иметь AtomicEnum в Java?

Класс AtomicEnum является this

  1. Как можно исследовать, если он делает операцию атомарен?
  2. Есть ли инструмент для просмотра скомпилированного кода и быть уверенным, что он действительно все только в одной машинной инструкции?
  3. Возможно ли открыть его из кода?
  4. Итак, если этот Atomic enum работает, у меня может быть атрибут AtomicEnum, и можно будет безопасно использовать его без волатильного ключевого слова и синхронизированных геттеров и сеттеров?
+0

Попробуйте найти зеркало для файла, потому что ссылка мертва. – vbence

ответ

13

Сегодня я увидел этот вспомогательный класс для AtomicEnum, но мне интересно, если это возможно, чтобы иметь атомное перечисление, почему он не входит в стандартные библиотеки Java?

AtomicEnum класс, который вы связаны только оберточной класс AtomicReference, который дает одновременный доступ к любому Object.

Действительно, все, что вам нужно, если у вас есть несколько потоков, которые получают и устанавливают его одновременно. Ключевое слово volatile гарантирует, что обновления, сделанные одним потоком, будут видны другими потоками. Вам нужен AtomicReference, если вам нужно сделать тип метода compareAndSet(...) - атомно проверить, является ли поле конкретным значением и только затем его обновить.

Как проверить, выполняются ли операции атомарно?

AtomicReference является частью классов java.util.concurrent, которые хорошо протестированы.

Есть ли инструмент для просмотра скомпилированного кода и быть уверенным, что он действительно работает только в одной машинной инструкции?

Это не должно быть необходимо. Вы можете посмотреть источник AtomicReference, если хотите посмотреть, что он делает. К сожалению, настоящая магия находится в собственном коде sun.misc.Unsafe.

Возможно ли открыть его из кода?

Это не должно быть необходимо.

Итак, если это Атомное перечисление работает, у меня может быть атрибут AtomicEnum, и можно будет безопасно использовать его без летучих ключевых слов и синхронизированных геттеров и сеттеров?

Да, AtomicReference обертывания volatile V value, так что вы не должны делать это.

+1

Спасибо. Итак, если я завершу любой объект с помощью атомной ссылки, он будет полностью потокобезопасным, включая все его атрибуты? Или это возможно только для неизменяемого объекта, такого как перечисление? поэтому я смогу быть уверенным, что если я заменил enum на атомный enum, то в этом примере никакой объект не будет блокировать мой класс? http://stackoverflow.com/questions/20685372 – Johnny

+3

Нет. Он только защищает ссылку. Если вы хотите иметь изменяемый объект, вам нужно синхронизировать его более интенсивно. –

+1

Enum's по умолчанию является потокобезопасным. «AtomicReference» делает ваш _field_ атомарным, поэтому несколько потоков могут тестировать и изменять его на другой enum atomically @Johnny. – Gray

3

Это AtomicEnum - это просто тонкая обертка вокруг AtomicReference, что имеет смысл, так как значение n enum - это просто объект (ссылка).

Так еслиAtomicReference работает правильно (и я думаю, мы можем предположить, что), то AtomicEnum будет работать.

+0

Поскольку Enums имеют уникальный целочисленный идентификатор («порядковый номер»), не лучше ли было бы использовать AtomicInteger? –

+0

@androiddeveloper: вы могли бы, но я действительно не вижу преимущества. Хранение ординала менее экономит (вы можете хранить что-то вне диапазона), требует больше работы для хранения/восстановления (отображение в/из фактического перечисления) и такое же пространство для хранения на большинстве платформ (определенно на 32-битных платформах и обычно [даже на 64-битных платформах] (https://wikis.oracle.com/display/HotSpotInternals/CompressedOops)). –

+0

Я вижу. Спасибо. –

1

Доступ к ссылке является атомарным, но доступ к объекту не является. Таким образом, изменение значения ссылки будет правильно распространено во всех потоках, но изменение фактического объекта перечисления может и не быть.
Пример ...

enum Weekdays { 
    public int rank = 0; 
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY; 
} 

Случай 1:

AtomicEnum<Weekdays> today = Weekdays.TUESDAY; 

Каждый обмен нитка 'сегодня' будет иметь ссылку на Weekdays.TUESDAY

Случай 2:

today.rank = 3; 

Нет гарантии, что каждый поток будет иметь обновленный ранг. (ранг не является изменчивым. Каждый хранит отдельную копию объекта в кеше.)

Таким образом, доступ к ссылке является атомарным, но для объекта это не так.
Примечание:
1) Атомный доступ не означает выполнение в одной машинной инструкции. Но логически это можно так подумать. Хотя он неделим, он может содержать несколько инструкций.
2) Даже если такой инструмент существует, было бы сложно проверить его, поскольку процесс обновления почти непредсказуем. Таким образом, возможны ложные положительные результаты.

Надеюсь, это поможет.

+0

Вы указали хороший момент, которого я не знал: «Атомный доступ не означает выполнение в одной машинной инструкции». благодаря! – Johnny

+0

Если у вас есть AtomicEnum (или действительно любая AtomicReference), единственный способ получить доступ к фактическому объекту - через поле volatile или более тяжелую синхронизацию, так что случай 2 тоже не является проблемой. То есть msgstr "изменение фактического объекта перечисления может не быть" неправильным. Но это смешивает различия между атомными операциями (запись в int является атомарной по определению, хотя) и гарантии видимости. У вас могут быть атомные операции, которые не дают вам никаких гарантий видимости, хотя это редко. – Voo

+0

Вы правы, но если вы не использовали поле volatile или более тяжелую синхронизацию (как в данном случае), «изменение фактического объекта перечисления может быть не видимым». Я просто старался использовать простой случай и избегать редких случаев для простоты. –

0

Я думаю, что нет никакого смысла писать такой класс. На самом деле, если вы пишете такой класс, вам нужно пересмотреть вопрос об ответственности класса. ENUMs абсолютно потокобезопасны, поэтому я не уверен, почему кому-то нужен AtominEnum, или это просто какой-то класс, который является Atomic, а также использует некоторый enum, но затем называет его AtomicEnum очень запутанным, не очень хорошо подходит для разработки или соглашения об именах.

Смежные вопросы