数据竞赛和安全发布

时间:2017-09-02 22:36:56

标签: java multithreading

@State
@JCStressTest
public class M {
    class A {
        int f;
        A() {
            f = 42;
        }
    }
    private A a;

    @Actor
    void actor1(){
        a = new A();
    }
    @Actor
    void actor2(IntResult1 r){
        r.r1 = 1;
        if(a != null){
            r.r1 = a.f;
        }
    }
}

我用jcstress测试了它,我无法得到输出0。我知道我应该看到输出并不明显,但这是可能的,我希望看到它。是否有任何JVM选项(如XX:....)来强制执行它?

1 个答案:

答案 0 :(得分:2)

  

我知道我应该看到输出并不明显,但这是可能的,我希望看到它。

您的代码确实存在数据竞争是正确的。

(根据JMM中规定的规则,f = 42... = a.f之间没有发生在链之前。因此,它不是保证< / em> a.f将始终看到值42。)

然而,这场比赛的性质是这样的,它只会出现在非常罕见的场景中。它很可能需要一个具有多个内核的系统,以及高内存负载或在错误的瞬间切换的非自愿线程上下文。它将取决于JIT编译器 1 发出的本机代码。

  

是否有任何JVM选项(如XX:....)来强制执行它?

不幸的是,没有。

1 - 请注意,您无法从字节码中获取声音推断。 JIT编译器允许(由JLS / JVMS)重新排序指令,包括内存读取和写入,前提是它们不违反JMM规则。这对于多线程代码的性能非常重要。