在此代码中:
public class PossibleReordering {
static int x = 0, y = 0;
static int a = 0, b = 0;
public static void main(String[] args)
throws InterruptedException {
Thread one = new Thread(new Runnable() {
public void run() {
a = 1;
x = b;
}
});
Thread other = new Thread(new Runnable() {
public void run() {
b = 1;
y = a;
}
});
one.start(); other.start();
one.join(); other.join();
System.out.println("( "+ x + "," + y + ")");
}
}
他们说Java Compiler将重新排序第一个线程中的指令,并将其他线程重新排序以优化其执行,最后导致结果(0,0)。
他们也说:
线程中的每个操作都发生在该线程中的每个操作之前,该操作在程序顺序中稍后出现。
这两个陈述是否相互冲突?
答案 0 :(得分:2)
before-before规则仅适用于彼此依赖的语句。由于这些run()
方法都包含独立的赋值,因此允许编译器对它们进行重新排序,这可能会导致您描述的输出。
您可以在Javaspecs here中阅读happens-before
的定义:
应该注意的是,两个动作之间存在先发生关系并不一定意味着它们必须采取 在实现中按顺序放置。如果重新排序产生 结果与法律执行一致,这不违法。
例如,如果第一个run()
方法如下所示:
public void run() {
b = 1;
x = b;
}
不允许重新排序。