Реальное использование и объяснение класса AtomicLongFieldUpdate

Кто-нибудь знает о реальном использовании класса AtomicLongFieldUpdate? Я прочитал описание, но не совсем понял его значение. Почему я хочу это знать? Любопытство и для подготовки OCPJP.

Заранее спасибо.

5 ответов

Вы можете думать о ценовой лестнице для следующего:

  • обычный long: дешево, но небезопасно для многопоточного доступа
  • volatile long: дороже, безопаснее для многопоточного доступа, атомарные операции невозможны
  • AtomicLong: самый дорогой, безопасный для многопоточного доступа, возможны атомарные операции

(Когда я говорю "небезопасно" или "невозможно", я имею в виду "без внешнего механизма, такого как синхронизация".)

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

Вот хороший маленький учебник.

Причина, по которой вы могли бы использовать, например, AtomicLongFieldUpdater вместо AtomicLong, заключается в простом снижении стоимости кучи. Внутренне оба работают почти одинаково на уровне CompareAndSet, который в конце использует sun.misc.Unsafe.

Предположим, у вас есть определенный класс, который инициализируется 1000 000 раз. С AtomicLong вы бы создали 1000k AtomicLongs. С другой стороны, с AtomicLongFieldUpdater вы бы создали 1 примитив CONSTANT AtomicLongFieldUpdater и 1000 тыс., Которые, конечно, не требуют так много места в куче.

Кто-нибудь знает о реальном использовании AtomicLongFieldUpdate учебный класс?

Я никогда не использовал этот класс сам, но при использовании get в своей рабочей области я вижу пару "реальных" примеров его использования:

  • com.google.common.util.concurrent.AtomicDouble использует его для атомной модификации их внутренних volatile long поле, которое хранит биты из double с помощью Number.doubleToRawLongBits(...), Довольно круто.

  • net.sf.ehcache.Element использует его для атомарного обновления hitCount поле.

Я прочитал описание, но не совсем понял его значение.

Это в основном обеспечивает ту же функциональность, что и AtomicLong но на поле, локальное для другого класса. Загрузка памяти AtomicLongFieldUpdate меньше чем AtomicLong тем, что вы конфигурируете один экземпляр обновления для каждого поля, что снижает нагрузку на память, но увеличивает нагрузку на процессор (хотя и может быть небольшой) из-за отражения.

Javadocs говорят:

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

Конечно, но тогда я бы просто использовал несколько Atomic* поля. Примерно единственная причина, по которой я бы использовал этот класс, это наличие существующего класса, который я не мог бы изменить, и который я хотел бы увеличить атомарно.

Конечно. Я недавно читал Alibaba Druid . я нашел AtomicLongFieldUpdater широко используется в этом проекте.

      
// stats
    private volatile long                    recycleErrorCount         = 0L;
    private volatile long                    connectErrorCount         = 0L;
protected static final AtomicLongFieldUpdater<DruidDataSource> recycleErrorCountUpdater
            = AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "recycleErrorCount");
    protected static final AtomicLongFieldUpdater<DruidDataSource> connectErrorCountUpdater
            = AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "connectErrorCount");

Как определено выше, свойства recycleErrorCountа также connectErrorCountиспользуются для подсчета времени возникновения ошибки. Довольно много DataSource(Класс, который содержит указанные выше свойства) будет создан в течение срока службы приложения, и в этом случае будет использоваться ALFUочевидно, уменьшает потребление пространства кучи, чем использование AtomicLong.

Атомика обычно используется в параллельном программировании.

В режиме кражи работы он поддерживает только асинхронные, финишные, форасинхронные, изолированные и атомарные переменные.

Вы можете рассматривать атомную защиту как надежную защиту от гонки данных и других проблем, которые необходимо учитывать при параллельном программировании.

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