Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 具有易失性写入的本地内存可见性_Java_Concurrency_Volatile - Fatal编程技术网

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

据我所知,新的java内存模型要求对易失性变量的访问不随对其他变量的访问而重新排序,因此以下是正确的:

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)耦合。