以下JCStress测试的描述:
@JCStressTest
@Outcome(id = {"0, 1", "1, 0", "1, 1"}, expect = ACCEPTABLE, desc = "Trivial under sequential consistency")
@Outcome(id = "0, 0", expect = FORBIDDEN, desc = "Violates sequential consistency")
@State
public static class VolatileDekker {
volatile int x;
volatile int y;
@Actor
public void actor1(II_Result r) {
x = 1;
r.r1 = y;
}
@Actor
public void actor2(II_Result r) {
y = 1;
r.r2 = x;
}
}
说:
向 $x 和 $y 添加 volatile 将它们组合在一起 同步顺序,因而要求结果一致 当读/写形成全序时的情况。
解释为什么结果
"0,0"
是不可能的。然而,x
和y
被放在一起成为同步顺序的原因是什么?引用《Java并发实践》
当线程A写入一个易失性变量并且随后 线程 B 读取同一个变量,即所有变量的值 在写入 volatile 变量之前对 A 可见,之后对 B 可见 读取易失性变量。
关于发生之前的关系,我假设编译器:
使编译器能够:
因此产生以下代码:
@Actor
public void actor1(II_Result r) {
r.r1 = y;
x = 1;
}
@Actor
public void actor2(II_Result r) {
r.r2 = x;
y = 1;
}
可以得到
0,0
的结果,但似乎不可能。
你是对的。理论上是有可能得到
(0,0)
结果的。测试不会失败,因为实现没有进行重新排序,但根据规范这是可能的。