Java 为什么JMM产生(0,0),即使它被认为是禁止的结果

Java 为什么JMM产生(0,0),即使它被认为是禁止的结果,java,concurrency,java-memory-model,Java,Concurrency,Java Memory Model,我正在检查JMM的一些语句,并编写了一个JCS测试,如下所示: @JCStressTest @State @Outcome(expect = ACCEPTABLE, desc = "ACCEPTABLE") public class ConcurrencyTest { private final int a = 1; private final int b = 2; public ConcurrencyTest instance;

我正在检查JMM的一些语句,并编写了一个JCS测试,如下所示:

@JCStressTest
@State
@Outcome(expect = ACCEPTABLE,  desc = "ACCEPTABLE")
public class ConcurrencyTest {
    private final int a = 1;
    private final int b = 2;

    public ConcurrencyTest instance;
    
    @Actor
    public void actor1() {
        instance = new ConcurrencyTest();
    }

    @Actor
    public void actor2(II_Result result) {
        ConcurrencyTest c = instance;
        if (c != null) {
            result.r1 = c.a;
            result.r2 = c.b;
        }
    }
}
运行此测试后,我看到以下结果:

(0,0)(1,2)


尽管JMM明确指出结果(0,0)是禁止的,但为什么会发生这种情况?

让我们先稍微修改一下代码:

@JCStressTest
@State
@Outcome(id = "0, 0", expect = Expect.FORBIDDEN)
@Outcome(id = "1, 2", expect = Expect.ACCEPTABLE)
@Outcome(id = "-1, -1", expect = Expect.ACCEPTABLE)
public class ConcurrencyTest {

    private final int a = 1;
    private final int b = 2;

    public ConcurrencyTest instance;

    @Actor
    public void actor1() {
        instance = new ConcurrencyTest();
    }

    @Actor
    public void actor2(II_Result result) {
        ConcurrencyTest c = instance;
        if (c != null) {
            result.r1 = c.a;
            result.r2 = c.b;
        } else {                   // <-- this is what you care about
            result.r1 = -1;
            result.r2 = -1;
        }
    }
}
@JCStressTest
@陈述
@结果(id=“0,0”,预期=预期。禁止)
@结果(id=“1,2”,expect=expect.可接受)
@结果(id=“-1,-1”,expect=expect.ACCEPTABLE)
公共类并发测试{
私人最终INTA=1;
私人最终int b=2;
公共并发测试实例;
@演员
公营机构1(){
实例=新的并发测试();
}
@演员
公开作废actor2(II_结果){
ConcurrencyTest c=实例;
如果(c!=null){
结果r1=c.a;
结果r2=c.b;

}否则{//为什么?
c
读取
null
r1
r2
都保持为零。@AndrewVershinin,JCS是否会输出结果变量状态,即使它没有更新?@Ilya不熟悉它,但会假定是。@Ilya作为前面的评论员,我不熟悉JCStress,但来自wh目前,我已经阅读了,它试图以不同的方式交错参与者(线程)以获得所有可能的执行结果。在
actor1
actor2
读取
实例之前完成的情况下,
(0,0)
结果实现了。谢谢,这确实是这种情况下唯一合理的行为。