Синхронизированный энергозависимый логический тип равен atomicBoolean?
Volatile следует использовать, когда мы выполняем только операцию чтения переменной, поскольку значение, обновленное одним потоком, будет видно другому, даже если предыдущий поток потеряет ЦП и выйдет из синхронизированного блока. Это верно? Атомные примитивы будут использоваться, когда нужно использовать атомарное поведение. Например -
if (volatileBoolean) {
volatileBoolean = !volatileBoolean;
}
Давайте предположим, что значение volatileBoolean равно true. Один поток проверяет volatileBoolean как true и входит в блок if, второй поток, видящий значение volatileBoolean как true, также входит в блок if. Теперь предположим, что первый поток назначает ложное значение (! VolatileBoolean) переменной volatileBoolean и теряет процессор, следовательно, выходит из блока if. Второй поток видит volatileBoolean как false, присваивает ему значение true.
В этом случае следует использовать AtomicBoolean? Если да, почему это не может быть обработано с помощью синхронизированного?
synchronized(this){
if (volatileBoolean) {
volatileBoolean = !volatileBoolean;
}
}
4 ответа
В этом случае следует использовать AtomicBoolean?
Да, это.
Если да, почему это не может быть обработано с помощью синхронизированного?
Это функционально эквивалентно, но AtomicBoolean не использует блокировку, которая может быть более эффективной при умеренной конкуренции. Посмотрите на этот другой вопрос - он смотрит на AtomicInteger, но выводы напрямую применимы и к AromicBoolean.
AtomicBoolean и любой AtomicSomething просто реализованы с использованием volatile. Единственное отличие состоит в том, что эти AtomicSomething содержат несколько методов для выполнения синхронизации без синхронизированного ключевого слова, например, CompareAndSet или lazySet. Так что вы, вероятно, должны использовать AtomicBoolean в вашем случае.
Да, это тот случай, когда вы захотите использовать AtomicBoolean. Это довольно хороший и безопасный способ добиться синхронизации, о которой вы упоминали (вместо того, чтобы делать это самостоятельно), и это намного быстрее. Также обратитесь к этой ссылке для сравнения с использованием volatile boolean в качестве альтернативы.
Volatile следует использовать, когда мы выполняем только операцию чтения переменной, поскольку значение, обновленное одним потоком, будет видно другому, даже если предыдущий поток потеряет ЦП и выйдет из синхронизированного блока. Это верно?
- volatile не имеет никакой зависимости от синхронизированного блока. изменчивые переменные не кэшируются потоком. Таким образом, изменения одного потока будут видны другим потокам.
- Таким образом, переменные переменные могут использоваться, когда запись / обновление в переменной выполняется одним потоком, и обновление должно быть немедленно видимым для всех других потоков, обращающихся к переменной. volatile обеспечивает только видимость, а не атомарность.
В этом случае следует использовать AtomicBoolean? Если да, почему это не может быть обработано с помощью синхронизированного?
- Да, если вы используете синхронизированный блок, нам не нужно использовать переменную volatile, поскольку синхронизированный блок обеспечит видимость и атомарность для общих данных. Волатильные чтения немного дороже, чем энергонезависимые чтения в большинстве современных процессорных архитектур.
Об AtomicBoolean
AtomicBoolean внутренне использует volatile int и операции CAS для обеспечения видимости и атомарности.
AtomicBoolean.java
public class AtomicBoolean implements java.io.Serializable {
private volatile int value;
/**
* Creates a new {@code AtomicBoolean} with the given initial value.
*
* @param initialValue the initial value
*/
public AtomicBoolean(boolean initialValue) {
value = initialValue ? 1 : 0;
}
Из книги Java Concurrency In Practice, посвященной изменчивым переменным.
Язык Java также предоставляет альтернативную, более слабую форму синхронизации, изменчивых переменных, чтобы гарантировать, что обновления переменной распространяются предсказуемо на другие потоки. Когда поле объявляется как volatile, компилятор и среда выполнения уведомляются о том, что эта переменная является общей и что операции с ней не должны переупорядочиваться с другими операциями с памятью. Используйте изменчивые переменные только тогда, когда они упрощают реализацию и проверку вашей политики синхронизации; Избегайте использования изменчивых переменных, когда проверка правильности потребует тонких рассуждений о видимости. Хорошее использование изменчивых переменных включает обеспечение видимости их собственного состояния, состояния объекта, к которому они относятся, или указание того, что произошло важное событие жизненного цикла (такое как инициализация или завершение работы).