【发布时间】:2021-10-10 17:22:39
【问题描述】:
我有这个简单的 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]) 观察到的状态发生期望解释
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
0, 1, 1, 0 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
1, 1, 1, 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]) 观察到的状态发生期望解释
1、1、1、1 100,299,061 ACCEPTABLE_INTERESTING
为什么 volatile 不能修复竞争条件,而 static 关键字可以修复它?还是 Jcstress 问题?
【问题讨论】:
标签: java concurrency static volatile jcstress