Когда мне нужно использовать AtomicBoolean в Java? - PullRequest
198 голосов
/ 21 декабря 2010

Как я могу использовать AtomicBoolean и для чего этот класс?

Ответы [ 5 ]

210 голосов
/ 21 декабря 2010

Когда нужно несколько потоков проверить и изменить логическое значение. Например:

if (!initialized) {
   initialize();
   initialized = true;
}

Это не потокобезопасно. Вы можете исправить это, используя AtomicBoolean:

if (atomicInitialized.compareAndSet(false, true)) {
    initialize();
}
47 голосов
/ 21 декабря 2010

Вот заметки (из книги Брайана Гетца ), которые я сделал, которые могут быть вам полезны

классы AtomicXXX

  • обеспечивает неблокирующую реализацию сравнения и замены

  • Воспользуйтесь преимуществами поддержки аппаратно (инструкция CMPXCHG на Intel) Когда много потоков пробегая ваш код, который использует эти атомарные параллелизм API, они будет масштабироваться намного лучше, чем код который использует уровень объекта мониторы / синхронизация. Поскольку, Механизмы синхронизации Java заставляет код ждать, когда много потоков, проходящих через ваш критические секции, существенная количество процессорного времени тратится в управление синхронизацией сам механизм (ожидание, уведомление, так далее). Поскольку новый API использует оборудование конструкции уровня (атомарные переменные) и ждать и заблокировать бесплатные алгоритмы реализовать потокобезопасность, намного больше процессорного времени тратится на "выполнение вещей" а не в управлении синхронизации.

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

31 голосов
/ 21 декабря 2010

Есть две основные причины, по которым вы можете использовать атомное логическое значение.Во-первых, его изменяемый, вы можете передать его как ссылку и изменить значение, связанное с самим логическим значением, например.

public final class MyThreadSafeClass{

    private AtomicBoolean myBoolean = new AtomicBoolean(false);
    private SomeThreadSafeObject someObject = new SomeThreadSafeObject();

    public boolean doSomething(){
         someObject.doSomeWork(myBoolean);
         return myBoolean.get(); //will return true
    }
}

и в классе someObject

public final class SomeThreadSafeObject{
    public void doSomeWork(AtomicBoolean b){
        b.set(true);
    }
}

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

17 голосов
/ 21 декабря 2010

Класс AtomicBoolean дает вам логическое значение, которое вы можете обновлять атомарно.Используйте его, когда несколько потоков обращаются к логической переменной.

Обзор пакета java.util.concurrent.atomic дает хорошее общее описание того, что делают классы в этом пакетеи когда их использовать.Я бы также порекомендовал книгу Брайана Гетца " Java Concurrency in Practice" .

5 голосов
/ 21 декабря 2010

Выдержка из описания пакета

Пакет java.util.concurrent.atomic description: Небольшой инструментарий классов, поддерживающий поточно-ориентированное программирование без единой переменной для отдельных переменных. [...]

Спецификации этих методов позволяют реализациям использовать эффективные атомарные инструкции машинного уровня, доступные на современных процессорах. [...]

Экземпляры классов AtomicBoolean, AtomicInteger, AtomicLong и AtomicReference предоставляют доступ и обновления к одной переменной соответствующего типа. [...]

Эффекты памяти для доступа и обновлений атомных компонентов обычно следуют правилам для летучих:

  • get имеет эффекты памяти чтения изменяемой переменной.
  • set имеет эффекты памяти записи (присваивания) энергозависимой переменной.
  • weakCompareAndSet атомарно считывает и условно записывает переменную, упорядочивается по отношению к другим операциям памяти с этой переменной, но в остальном действует как обычная операция энергонезависимой памяти. compareAndSet и все другие операции чтения и обновления, такие как getAndIncrement, влияют на память как чтения, так и записи изменчивых переменных.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...