Когда мне нужно использовать AtomicBoolean в Java?

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

Ответ 1

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

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

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

if (atomicInitialized.compareAndSet(false, true)) {
    initialize();
}

Ответ 2

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

Классы AtomicXXX

  • обеспечить неблокирующую реализацию Compare-And-Swap

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

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

Ответ 3

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

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, вы должны синхронизировать логическую переменную, которую используете, объявив ее изменчивой или синхронизированной вокруг чтения и записи поля.

Ответ 4

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

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

Ответ 5

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

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

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

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

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

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