【发布时间】:2017-06-04 07:44:16
【问题描述】:
我正在尝试调查在 java 环境中重新排序的行为(使用 JDK 9-ea+170)并发现了一件我无法为自己解释的事情,所以我很高兴听到一些关于它的说明。这是一个例子:
public class Client {
int x;
int y;
public void test() {
x++;
y++;
}
public static void main(String[] args) {
Client c = new Client();
while(c.y <= c.x) new Thread(() -> c.test()).start();
System.out.println(c.x + " " + c.y);
}
}
这个程序有一个 test() 方法,它只增加 x 和 y 值。我正在创建新线程并调用它test(),直到一些内部 java 优化不改变x++; y++;指令()的顺序。这样我证明重新排序确实发生了。并且程序大部分时间都结束了(这是预期的)。
现在我给 y 添加了 volatile 修饰符:
public class Client {
int x;
volatile int y;
public void test() {
x++;
y++;
}
public static void main(String[] args) {
Client c = new Client();
while(c.y <= c.x) new Thread(() -> c.test()).start();
System.out.println(c.x + " " + c.y);
}
}
这个程序永远不会结束,因为 volatile 保证 volatile 之前的所有指令都将被刷新到内存中,所以 x++; 总是在 y++; 之前执行,并且不可能有 y > x。这也是我理解的预期。但在那之后,我也将 volatile 添加到 int x;,现在我可以再次看到重新排序,所以程序大部分时间都结束了:
public class Client {
volatile int x;
volatile int y;
public void test() {
x++;
y++;
}
public static void main(String[] args) {
Client c = new Client();
while(c.y <= c.x) new Thread(() -> c.test()).start();
System.out.println(c.x + " " + c.y);
}
}
为什么还要在这里进行重新排序?
【问题讨论】:
标签: java concurrency volatile java-memory-model