我有这个简单的 Jcstress 测试:
package io.denery;
import org.openjdk.jcstress.annotations.*;
import org.openjdk.jcstress.infra.results.IIII_Result;
@JCStressTest
@Outcome(expect = Expect.ACCEPTABLE_INTERESTING)
@State
public class RaceIRIWTest {
volatile int x, y;
@Actor
public void actor1() {
x = 1;
}
@Actor
public void actor2() {
y = 1;
}
@Actor
public void actor3(IIII_Result r) {
r.r1 = x;
r.r2 = y;
}
@Actor
public void actor4(IIII_Result r) {
r.r3 = y;
r.r4 = x;
}
}
但是这个测试的结果是:
[OK] io.denery.RaceIRIWTest(JVM 参数:[-XX:+UnlockDiagnosticVMOptions,-XX:+WhiteBoxAPI,-XX:-RestrictContended,-Dfile.encoding=UTF-8,-Duser.country=RU,-Duser。 language=en, -Duser.variant, -XX:-TieredCompilation, -XX:+StressLCM, -XX:+StressGCM, -XX:+StressIGVN]) Observed state Occurrences Expectation Interpretation
0, 0, 0, 0 22,180,923 ACCEPTABLE_INTERESTING
0, 0, 0, 1 721,581 ACCEPTABLE_INTERESTING
0, 0, 1, 0 13,347 ACCEPTABLE_INTERESTING
0, 0, 1, 1 456,971 ACCEPTABLE_INTERESTING
0, 1, 0, 0 344,068 ACCEPTABLE_INTERESTING 0, 1, 0
, 1, 36 ACCEPTABLE_INTERESTING
528,641 ACCEPTABLE_INTERESTING
0, 1, 1, 1 258,265 ACCEPTABLE_INTERESTING
1, 0, 0, 0 204,088 ACCEPTABLE_INTERESTING
1, 0, 0, 1 667,580 ACCEPTABLE_INTERESTING
1, 0, 1, 1 94,877 ACCEPTABLE_INTERESTING
1, 1, 0, 0 663,159 ACCEPTABLE_INTERESTING 1 ,
1, 0, 1 306,251 ACCEPTABLE_INTERESTING
, 0 128,608 ACCEPTABLE_INTERESTING
1, 1, 1, 1 18,838,186 ACCEPTABLE_INTERESTING
我们看到了竞态条件,但是如果我放入static
并volatile int x, y
删除volatile
关键字,那么 jcstress 测试的结果将是:
[OK] io.denery.RaceIRIWTest(JVM 参数:[-XX:+UnlockDiagnosticVMOptions,-XX:+WhiteBoxAPI,-XX:-RestrictContended,-Dfile.encoding=UTF-8,-Duser.country=RU,-Duser。 language=en, -Duser.variant, -XX:-TieredCompilation, -XX:+StressLCM, -XX:+StressGCM, -XX:+StressIGVN]) Observed state Occurrences Expectation 解释
1, 1, 1, 1 100,299,061 ACCEPTABLE_INTERESTING
为什么 volatile 不修复竞争条件,但 static 关键字修复它?或者这是一个 Jcstress 问题?