使用volatile原语而不是primefaces变量有什么区别?

可能重复:
Java:volatile boolean vs AtomicBoolean

什么时候使用volatile原语(例如booleanintegerlong )而不是AtomicBooleanAtomicIntegerAtomicLong ,反之亦然?

可见性语义完全相同,使用primefaces基元很有用的情况是当你需要使用它们的primefaces方法时。

例如:

 if (volatileBoolean) { volatileBoolean = !volatileBoolean; } 

可能会在multithreading环境中创建问题,因为变量可能会在两行之间发生变化。 如果您需要测试和分配是primefaces的,您可以使用:

 atomicBoolean.compareAndSet(true, false); 

如果要设置或获取值,则使用普通volatile可以更简单,更高效。 (但没有得到&设定值)

如果需要更多操作,如getAndIncrement或compareAndSwap,则需要使用AtomicXxxx类。

Atomic*类包装了相同类型的volatile原语。 从来源:

 public class AtomicLong extends Number implements java.io.Serializable { ... private volatile long value; ... public final long get() { return value; } ... public final void set(long newValue) { value = newValue; } 

所以。

何时使用volatile原语(例如boolean,integer或long)而不是AtomicBoolean,AtomicInteger或AtomicLong

如果您正在做的就是获取并设置Atomic*那么您可能只需要使用volatile字段。

……反之亦然?

然而, Atomic*类为您提供的方法是提供更高级function的方法,例如incrementAndGet()compareAndSet()以及其他实现多个操作(get / increment / set,test / set) 而无需锁定的方法。 这就是Atomic*类如此强大的原因。

同样重要的是要注意,使用Atomic*类包装volatile字段是从对象角度封装关键共享资源的好方法。 这意味着开发人员不能只处理该字段,假设它没有共享可能注入field++;问题field++; 或引入竞争条件的其他代码。

我们已经开始禁止在我们的源代码中使用volatile ,因为编写代码并不总是按预期工作。

根据我的经验,人们添加volatile来在线程之间共享一个值。 然后,其他人开始修改该值。 而且大多数时候,这都有效。 但在生产中,你开始出现奇怪的错误,这些错误很难追查。 计数器增加100’000次(测试只增加10次)但最终为99’997。 在Java 1.4中,长值可能真的很少被破坏。

另一方面, Atomic*帮助程序类只需要很小的开销,它们总是像宣传的那样工作。

因此,除非你有一个非常好的理由(*)使用volatile ,否则总是更喜欢Atomic*辅助类。

如果你不确切知道Atomic* helper类中的每个字符是什么,那么你应该真的避免volatile

*:过早优化绝不是一个好理由。