【发布时间】:2020-05-07 01:13:13
【问题描述】:
我正在尝试使用多线程和以下示例:https://docs.oracle.com/javase/specs/jls/se10/html/jls-8.html#jls-8.3.1.4
我在下面发布了我的代码。
你能帮我理解为什么“if (x < y) {”会发生数据竞争而不是“if (y > x) {”吗?
我正在使用 openjdk-14.0.1:
Linux void-MS-7678 5.4.0-29-generic #33-Ubuntu SMP Wed Apr 29 14:32:27 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
代码:
public class Main {
public static void main(String[] args) {
DataRace dr = new DataRace();
Thread t1 = new Thread(()-> {
for (int i = 0; i < 100_000; i++) {
dr.increment();
}
});
Thread t2 = new Thread(()-> {
for (int i = 0; i < 100_000; i++) {
dr.check();
}
});
t1.start();
t2.start();
}
private static class DataRace {
private volatile int x = 0, y = 0;
public void increment() {
x++;
y++;
}
public void check() {
// System.out.println("x=" + x + " y="+ y); // - NO ISSUES
// if (y > x) { - NO ISSUES
// if (x < y) { - ISSUES
if (x < y) {
System.out.println("DataRace detected: x < y");
}
}
}
}
输出:
/home/void/.jdks/openjdk-14.0.1/bin/java -javaagent:/home/void/Development/idea-IC-183.4588.61/lib/idea_rt.jar=46411:/home/void/Development/idea-IC-183.4588.61/bin -Dfile.encoding=UTF-8 -classpath /home/void/Development/multithreading/out/production/classes Main
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
DataRace detected: x < y
Process finished with exit code 0
【问题讨论】:
-
volatile是关于更改的可见性,而不是竞争条件。 -
@akuzminykh 如果我正确理解了这个例子,就不应该有任何竞争条件。我们应该在 volatile 应该解决的 increment() 方法中进行乱序执行,但是我没有看到它按我预期的那样工作。
-
@JacobG。不,它没有帮助。这是更改后的代码:gist.github.com/bff38874/faefc79fbcbc08c30da5edcc1c7caf43
-
@JacobG.,
static没有理由改变任何东西。无论哪种方式,都有两个共享变量。static关键字改变了它们在内存中的位置,但它不会改变它们被两个不同的线程共享的事实,或者访问不同步的事实。 -
您的代码在“”两种情况下都会出现数据竞争。它们的频率将取决于 VM 版本。例如,它在 Amazon JVMv8 上展示了数十次数据竞争,而在 Amazon JVMv11 上最多展示了一次数据竞争 :)
标签: java multithreading volatile