在Java中使用易失性布尔值而不是原子布尔值何时更可取?

2022-08-31 16:53:43

我已经看过SO中的其他易失性与Atomicxxxx问题(包括这个),并阅读了java.util.current.atomic的描述,我对细微差别不太满意。

如果我试图在使用 和 之间做出决定,除了原子布尔提供的原子读取-修改-写入操作之外,是否存在实际差异?(例如 和volatile booleanAtomicBooleancompareAndSet()getAndSet())

假设我有

volatile boolean flag;

然后,一个或多个线程设置标志(但不清除它)。如果我有一个读取标志的线程,如果设置了,则操作然后清除标志是否足够?volatile

原子布尔值的成本是否高于易失性布尔值,就

  • 内存空间
  • 性能命中(似乎需要内存屏蔽,似乎需要内存屏蔽+根据java.util.current.atomic描述对CAS操作进行一些小的锁定)volatile booleanAtomicBoolean

我的直觉是使用AtomicBoolean并保持安全,但我想了解是否有一种情况可以使用(例如,如果我有数千个实例并且性能是一个问题)。volatile boolean


答案 1

从实际的角度来看,两者之间的主要区别在于比较和集合操作不是变量的原子。AtomicBooleanvolatilevolatile

 volatile boolean b;

 void foo() {
   if( b ) {
     //Here another thread might have already changed the value of b to false
     b = false;
   }
 }

但是,由于所有并发写入都是幂等的,并且您只能从一个线程读取,因此这应该不是问题。


答案 2

本质上,一切都是一个在一个对象中。AtomicBooleanvolatile boolean

每个对象的开销很小。可能微不足道,但可能有更多的内存进入缓存。

如果您需要使用,那么会有很多性能开销。如果你不打算经常这样做(就像在NIO中一样),那可能是可以的。AtomicBooleanFieldUpdaterattach


推荐