Java是否使用volatile关键字内存高效?

时间:2013-02-20 15:45:15

标签: java memory volatile memory-efficient

如果使用1个volatile变量,它是否会关闭其他相关非易失性变量的cpu缓存?

3 个答案:

答案 0 :(得分:2)

不,它只会阻止该变量被加载到cpu缓存并在那里进行修改。更确切地说,它在访问volatile字段后强制cpu刷新其缓存。有关详细信息,请参阅here

答案 1 :(得分:1)

它不会“关闭”缓存。但是,是的通常导致其他待处理写入的刷新(当您编写volatile时)或至少某些缓存失效时(当您读取volatile时)...这两者都使用额外的内存带宽,并对性能产生影响。

考虑这个例子:

public volatile int foo;
public int bar;

/* thread 1 */

bar = 1; // A
foo = 1; // B

/* thread 2 */
System.err.println("foo = " + foo);  // C
System.err.println("bar = " + bar);  // D

JLS表示A 发生在 B之前,C 发生在 D之前。如果线程2中的C 后续发生在B中线程1,然后B 发生在 C之前,因此A 发生在 D之前。

如果A 发生在 D之前,则在A处写入bar的值必须在D处可用bar ...假设没有其他内容写入{{ 1}}在此期间。

这是实现特定的如何实现。但肯定会对缓存数据产生影响......包括非易失性字段的缓存副本。

假设一个典型的内存架构,并假设线程1和线程2不共享缓存,这意味着:

  • 必须通过B处的主题1将barfoo刷新到主内存,并且
  • at C必须丢弃任何线程2的barfoo缓存副本。

我的理解是,这通常使用缓存无效和缓存刷新指令来实现。


最重要的是,使用bar会对多核系统产生重大的性能影响,因为它会产生额外的内存流量。

答案 2 :(得分:0)

volatile关键字与内存无关。这是一个并发问题。

修改 volatile关键字与内存效率无关。这是一个并发问题。