Java volatile读刷新写,volatile写更新读吗
我理解读获取(不在其后使用后续读/写操作重新排序)和写释放(不在之前使用读/写操作重新排序)。 我的问题是:-Java volatile读刷新写,volatile写更新读吗,java,multithreading,Java,Multithreading,我理解读获取(不在其后使用后续读/写操作重新排序)和写释放(不在之前使用读/写操作重新排序)。 我的问题是:- 在读获取的情况下,它前面的写操作是否被刷新 在写释放的情况下,以前的读取是否得到更新 另外,在Java中,读获取和volatile读相同,写释放和volatile写相同吗 这之所以重要,是因为,让我们以写释放为例 y = x; // a read.. let's say x is 1 at this point System.out.println(y);// 1 printed //
y = x; // a read.. let's say x is 1 at this point
System.out.println(y);// 1 printed
//or you can also consider System.out.println(x);
write_release_barrier();
//somewhere here, some thread sets x = 2
ready = true;// this is volatile
System.out.println(y);// or maybe, println(x).. what will be printed?
此时,是x2还是1?
在这里,考虑一下波动性。
我知道在volatile之前的所有商店都将首先可见。。然后,只有挥发物才可见。谢谢
参考:-对于您的第一个问题,答案是FIFO顺序
关于第二个问题:请检查否:并非所有写入都已刷新,也不是所有读取都已更新 Java在多线程“之前发生”的基础上工作。基本上,如果A发生在B之前,B发生在C之前,那么A发生在C之前。所以你的问题是
x=2
是否正式发生在某个读取x的动作之前
在基本上通过与中定义的关系进行同步来建立边之前发生。有几种不同的方法可以做到这一点,但对于volatile,它基本上相当于在读取同一volatile之前发生对volatile的写入:
- 对易失性变量v的写入(§8.3.1.4)与任何线程对v的所有后续读取同步(其中“后续”是根据同步顺序定义的)李>
ready=true
,那么单独写入并不意味着在它之前发生任何事情(就写入而言)。事实恰恰相反;如果它们读取ready
,则写入ready
的操作会在其他线程上的操作之前发生
因此,如果另一个线程(设置x=2
)在设置x=2
后已写入ready,而这个线程(您在上面发布的)则读取ready
,那么它将看到x=2
。这是因为写入发生在读取之前,因此读取线程可以看到写入线程所做的一切(包括写入)。否则,你就有了一场数据竞赛,基本上所有的赌注都输掉了
还有几点需要注意:
- 如果您没有“发生在前”边缘,您仍然可以看到更新;只是你不能保证会。因此,不要假设如果您没有读到write to
,那么您仍然会看到x=1。您可能会看到x=1或x=2,或者可能会看到其他写入(直到并包括默认值x=0)ready
- 在您的示例中,
始终为1,因为您不会在“此处某处”注释后重新读取y
。为了回答这个问题,我假设在x
之前或之后有第二行ready=true
。如果没有,那么y的值将与第一个y=x
中的值保持不变(假设没有其他线程直接更改它——如果它是局部变量,这是可以保证的),因为线程中的操作总是看起来好像没有重新排序一样println
在您的示例中,很明显,
y
在最后一行仍然是1。根据前面的输出,只有一个赋值给了y
,即1。也许这是一个输入错误,您打算编写println(x)
,但即使这样,2的值也不能保证是可见的。Java内存模型没有用“读取获取”和“写入释放”来指定。这些术语/概念来自其他上下文,正如您所引用的文章非常清楚地表明的,它们通常(由不同的专家)用于表示不同的事物
如果您想了解volatiles在Java中是如何工作的,您需要了解Java内存模型和Java术语。。。这(幸运的)是有充分的根据和精确的说明1。尝试将Java内存模型映射到“读取-获取”和“写入-释放”语义是一个坏主意,因为:
- “读取-获取”和“写入-发布”的术语和语义没有得到很好的规定,并且
- 假设的JMM->“读-获取”/“写-发布”语义映射只是JMM的一种可能实现。其他映射可能具有不同的、同样有效的语义
1-。。。专家们注意到JMM的某些版本中存在缺陷。但问题是,已经做出了认真的尝试,以提供一个理论上合理的规范。。。作为Java语言规范的一部分