synchronized volatile boolean是否等于atomicBoolean?

时间:2013-06-17 17:20:49

标签: java volatile atomicboolean

当我们仅对变量执行读取操作时应使用Volatile,因为一个线程更新的值对另一个线程可见,即使前一个线程丢失CPU并退出synchronized块。那是对的吗?当需要使用原子行为时,将使用原子基元。例如 -

if (volatileBoolean) {
    volatileBoolean = !volatileBoolean;
}

假设volatileBoolean的值为true。一个线程将volatileBoolean检查为true并输入if block,第二个线程将volatileBoolean的值视为true,同时输入if块。现在,假设第一个线程将假值(!volatileBoolean)分配给volatileBoolean变量并丢失CPU,因此退出if块。第二个线程将volatileBoolean视为false,将其指定为true。

这是应该使用AtomicBoolean的情况吗?如果是,为什么不能通过使用synchronized来处理?

synchronized(this){
        if (volatileBoolean) {
            volatileBoolean = !volatileBoolean;
        }
}

4 个答案:

答案 0 :(得分:2)

  

这是应该使用AtomicBoolean的情况吗?

是的。

  

如果是,为什么不能通过使用synchronized来处理?

它是功能等效的,但AtomicBoolean不使用锁,在中等争用下可以更有效。请参阅此other question - 它会查看AtomicInteger,但结论也直接适用于AromicBoolean。

答案 1 :(得分:0)

是的,这是你想要使用AtomicBoolean的情况。这是一种非常好且安全的方式来实现您提到的那种同步(而不是自己动手)并且速度更快。另请参阅this link以与使用volatile boolean作为替代进行比较。

答案 2 :(得分:0)

当我们仅对变量执行读取操作时应该使用Volatile,因为一个线程更新的值对另一个线程可见,即使前一个线程丢失CPU并退出synchronized块。这是对的吗?

  • volatile与synchronized块没有任何依赖关系。 volatile不会缓存volatile变量。因此,其他线程可以看到一个线程的更改。
  • 当变量的写入/更新由单个线程完成时,可以使用易变量变量,并且更新需要立即对访问变量的所有其他线程可见。 volatile只能确保可见性而不是原子性。

这是应该使用AtomicBoolean的情况吗?如果是,为什么不能通过使用synchronized?

来处理
  • 是,如果使用synchronized块,我们不需要在内部使用volatile变量,因为synchronized块将确保共享数据的可见性和原子性。在大多数当前处理器架构中,易失性读取比非易失性读取略贵。

关于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一书,关于volatile变量。

Java语言还提供了另一种较弱的同步形式,即volatile变量,以确保这一点 对变量的更新可预测地传播到其他传播。当一个字段被声明为volatile时,编译器和 运行时会注意到这个变量是共享的,并且对它的操作不应该与其他操作重新排序 记忆操作。 仅在简化实施和验证同步策略时使用volatile变量;避免使用 验证正确性时的volatile变量需要对可见性进行微妙推理。易挥发的好用途 变量包括确保自己状态的可见性,它们所引用的对象的可见性,或指示一个 发生了重要的生命周期事件(例如初始化或关闭)。

答案 3 :(得分:0)

AtomicBoolean和任何AtomicSomething都是使用volatile实现的。唯一的区别是那些AtomicSomething包含一些没有synchronized关键字进行同步的方法,例如compareAndSet或lazySet。所以你应该在你的情况下使用AtomicBoolean。