3

在这段代码中:

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编译器将重新排序线程一和线程另一中的指令以优化其执行,并最终导致结果(0,0)。

他们还说:
线程中的每个动作都发生在该线程中的每个动作之前,这些动作在程序顺序的后面出现。

这两种说法是否相互冲突?

4

1 回答 1

3

发生前规则仅适用于相互依赖的语句。由于这些run()方法都包含独立的赋值,因此允许编译器重新排序它们,这可能会导致您描述的输出。
您可以在此处happens-before阅读Javaspecs 中的定义:

应该注意的是,两个动作之间存在之前发生的关系并不一定意味着它们必须在实现中以该顺序发生。如果重新排序产生与合法执行一致的结果,则不是非法的。

例如,如果第run()一种方法如下所示:

public void run() {
    b = 1;
    x = b;
}

不允许重新排序。

于 2012-09-14T04:57:25.410 回答