JMM是否保证相同值的volatile覆写最终可见?线程终止性求证
volatile变量覆写相同值时的JMM可见性问题
JMM规定:当线程A对volatile变量V执行写入操作后,线程B读取V的值时,A的所有非volatile写入操作对B可见。那么当多次对volatile变量V覆写相同值时,该可见性保证是否依然成立?
示例Java代码如下:
int x = 0; int y = 0; volatile int v = 0; void fromThreadA() { x = 1; v = 0; y = 1; v = 0; // note that both writes to v never actually change its value } void fromThreadB() { while(v == 0) { if (x == 1 && y == 1) break; } }
请问是否能保证fromThreadB的调用者最终会终止?
不能保证fromThreadB最终终止
原因在于JMM的规范中,volatile的可见性保证依赖于写入操作触发的内存同步行为,但当写入的是与当前内存中相同的值时,JVM或底层处理器允许优化掉该写入对应的内存屏障和主内存刷新操作——因为从逻辑上看,值没有发生变化,同步操作没有必要。
回到示例代码:线程A两次对v写入0,而v的初始值就是0。JVM完全可能优化掉第二次v=0的写入操作,此时线程A中y=1的非volatile写入,没有对应的volatile写入来触发内存同步,无法保证该操作对线程B可见。线程B的循环中,可能始终看不到y=1,导致无法触发break,从而永远卡在循环里。
另外,即使第一次v=0的写入让x=1对线程B可见,但后续y=1的写入没有被同步到主内存,线程B会一直认为y=0,循环无法终止。
内容的提问来源于stack exchange,提问作者user3489275
相关产品推荐
相关产品推荐

