2

据我了解,新的 java 内存模型要求对 volatile 变量的访问不会随着对其他​​变量的访问而重新排序,因此以下代码是正确的:

Map configOptions;
char[] configText;
volatile boolean initialized = false;

// In Thread A
configOptions = new HashMap();
configText = readConfigFile(fileName);
processConfigOptions(configText, configOptions);
initialized = true;

// In Thread B
while (!initialized) 
  sleep();
// use configOptions 

所以什么时候initialized设置为true配置选项已经初始化了,但是它是可见的吗?我的意思是它已经在主内存中了吗?

4

2 回答 2

4

是的。从 Java 5 开始,访问 volatile 变量会创建一个内存屏障,它可以有效地将所有缓存变量的副本与主内存同步。

这被称为同步捎带,其中对非同步变量的写入使用对其他变量的后续同步来使用主存储器更新其值。

此外,在 volatile 上的读/写是昂贵的。不建议使用它来摆脱无限循环。如果它在某种程度上是不可避免的,至少使用Thread.sleep()某个地方。

参考资料:
易变的背驮。这足以可见性吗?

于 2013-05-28T07:29:12.573 回答
1

因此,当 initialized 设置为 true 时,配置选项已经初始化,但它是否可见?

的。一旦你让它volatile对所有线程可见并从main memory 根据Java 语言规范读取

Java 编程语言允许线程访问共享变量(第 17.1 节)。通常,为了确保共享变量始终如一且可靠地更新,线程应该通过获取锁来确保它对这些变量具有独占使用权,该锁通常对这些共享变量强制互斥。一个字段可能被声明为 volatile,在这种情况下,Java 内存模型确保所有线程都看到变量的一致值(第 17.4 节)。`

于 2013-05-28T07:28:58.503 回答