2015-02-20 4 views
0

Предполагая, что Java 6/7/8:Как обеспечить атомарность без AtomicInteger в java?

Есть ли какой-либо шанс маркировать некоторый оператор атома без использования, например, AtomicInteger? Из моих мини-исследований это кажется невозможным вообще, однако операции с целыми/байтовыми/char атомами сами по себе (source).

Очевидно, что есть synchronized, но в этот момент я бы хотел его избежать. Поэтому вопрос: могу ли я сделать что-то вроде atomic(x++)?

+0

Я не думаю, что есть способ. Фактическая установка примитива - это одна операция в любом случае (уже атомарная). Если вы произвольно решаете, что какой-то целый метод должен быть атомарным, вам придется его синхронизировать. Я думаю, что атомные классы действительно предоставляются только для удобства, потому что такие вещи, как увеличение числа, являются общими. – Richard

ответ

1

варианты:

  • внутренние замки через synchronized ключевое слово
  • с использованием явных блокировок от java.util.concurrent.locks завернуть операции, которые вы хотите сделать атомное
+1

Неправильно. Использование 'volatile' не является опцией, поскольку оно не делает' x ++ 'атомарным. – aioobe

2

Мой совет: если вы делаете многопоточное программирование, начните с синхронизации как можно скорее. Atomicity работает для небольших типов данных, но как только вы захотите получить доступ к экземплярам классов из разных потоков, вам нужно подумать о синхронизации, либо используя , либо явно манипулируя блокировками.

Хотя одиночные int чтения и записи являются атомарными в том смысле, что они не оставят переменную в несогласованном состоянии, это не единственное, что важно для атомарности. В частности, современные процессоры переупорядочивают инструкции и кэш-память, так что изменения в переменной могут быть недоступны для других потоков (это можно решить, добавив ключевое слово volatile к переменной.

Кроме того, AtomicInteger и друзья также предоставляют операции, которые состоят из нескольких операций, например, метода getAndIncrement(), который аналогичен оператору postfix ++.Это состоит из чтения и записи, а если вы не синхронизируете или не используете AtomicInteger, другие потоки могут получить доступ к переменной между чтение и запись.

+0

Что говорит этот парень. – aioobe

0

Если вы хотите читать и записывать переменные из нескольких потоков, тогда вам нужно наложить некоторую атомарность на переменные. не может полагаться на операции, являющиеся внутренне атомарными, потому что значение переменной может быть кэшировано потоком. Из-за этого обновление в одном потоке не может быть замечено другим потоком. Самый простой способ этого - объявить переменную volatile, которая заставляет считывать последнее значение. Классы java.util.concurrent предоставляют дополнительные функции и хорошую производительность.

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