java易失性会影响非易失性变量吗?
好吧,假设我有一堆变量,其中一个声明为volatile:
int a;
int b;
int c;
volatile int v;
如果一个线程写入所有四个变量(最后写入v
),另一个线程读取所有四个变量(首先读取v
),那么第二个线程是否看到第一个线程写入a
、b
和c
的值,即使它们本身没有声明为volatile?或者它可能看到陈旧的价值观吗
因为似乎有一些困惑:我不是故意做不安全的事。我只想了解Java内存模型和volatile
关键字的语义。纯粹的好奇心
# 1 楼答案
我要谈谈我认为你们可能真正在探索的东西——搭载同步
它看起来像是你试图使用的一种技术,包括使用一个易失性变量作为同步保护,与一个或多个其他非易失性变量配合使用。当下列条件成立时,此技术适用:
对于你的例子,你没有提到第二个条件成立,但我们还是可以检查它。writer的模型如下:
读卡器的操作如下:
如果volatile guard变量尚未指示正确的值,则读卡器不得读取其他非volatile变量
guard变量充当一个门。它将关闭,直到编写器将其设置为特定值,或所有值都满足指示闸门现在打开的条件。非易失性变量被保护在门后。在大门打开之前,读者是不允许阅读的。一旦闸门打开,读者将看到一组非易失性变量的一致视图
请注意,重复运行此协议是不安全的。一旦打开闸门,编写器就不能继续更改非易失性变量。此时,多个读卡器线程可能正在读取这些其他变量,它们可以查看这些变量的更新。看到一些但不是所有的更新会产生不一致的场景视图
备份时,这里的诀窍是控制对一组变量的访问,而无需
在易变的guard变量上搭载是一种聪明的特技,而不是随便做的特技。对程序的后续更新可以打破上述脆弱条件,消除Java内存模型提供的一致性保证。如果您选择使用这种技术,请在代码中清楚地记录其不变量和需求