Java 具有易失性写入的本地内存可见性
据我所知,新的java内存模型要求对易失性变量的访问不随对其他变量的访问而重新排序,因此以下是正确的:Java 具有易失性写入的本地内存可见性,java,concurrency,volatile,Java,Concurrency,Volatile,据我所知,新的java内存模型要求对易失性变量的访问不随对其他变量的访问而重新排序,因此以下是正确的: Map configOptions; char[] configText; volatile boolean initialized = false; // In Thread A configOptions = new HashMap(); configText = readConfigFile(fileName); processConfigOptions(configText, con
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
时,配置选项已初始化,但是否可见?我的意思是它已经在主内存中了吗
所以当initialized设置为true时,配置选项已经初始化,但它是否可见
是。一旦您将其设置为易失性
对所有线程可见,并从主存读取
依照
Java编程语言允许线程访问共享变量(§17.1)。通常,为了确保共享变量得到一致可靠的更新,线程应该通过获取锁来确保它独占使用这些变量,按照惯例,锁会强制这些共享变量互斥。
一个字段可以声明为volatile,在这种情况下,Java内存模型确保所有线程都能看到变量的一致值(§17.4)`
对。从Java 5开始,访问易失性变量会创建一个内存屏障,有效地将所有缓存变量的副本与主内存同步 这就是所谓的同步背驮(Synchronization Piggybacking),其中对非同步变量的写入使用对其他变量的后续同步,以使用主存更新其值 此外,在volatile上读/写也是昂贵的。不建议使用它来跳出无限循环。如果不可避免,至少在某个地方使用
Thread.sleep()
参考文献:configOptions
不是易失性的,只有initialized
是volatile,在initialized
上的读取操作将从主存中获取,而不是configOptions'线程将从其本地缓存读取configOptions`所有线程都将看到initialized
的最新更新,因为这是volatile。问题不在于initialized
变量,但是关于configOptions
,即使它可以工作,使configOptions
的可见性依赖于另一个变量的可见性也是非常脆弱的。您应该尽可能避免:a)顺序语义(“X是有效的,因为它发生在Y之前”)和b)耦合。