为什么在Java内存模型中对同一个变量的两次写入冲突?

nos*_*sid 5 java multithreading

所述不存在数据争用为前提顺序一致性.数据争用是由冲突的访问引起的.如果至少有一个访问是写,则对同一变量的两次访问是冲突的.

请参阅JLS7的以下引用以供参考.

我理解这种情况的定义,其中一个操作是读访问,另一个操作是写访问.但是,我不明白为什么需要(对于内存模型),如果对同一个变量有两个写操作.

问题:在对同一个变量进行两次写入操作的情况下,保证顺序一致性的理由是什么,这些操作不是由先发生关系排序的?


§17.4.1:[..] 如果至少有一个访问是写入,则对同一变量的两次访问(读取或写入)被认为是冲突的.

§17.4.5:[..]当一个程序包含两个冲突的访问时,这些访问不是由一个先发生的关系排序的,它被认为包含一个数据竞争.[..] 当且仅当所有顺序一致的执行没有数据争用时,程序才能正确同步.如果程序正确同步,则程序的所有执行将看起来是顺序一致的.

mer*_*ike 3

如果两个写访问不处于先发生关系,则未指定哪个将最后发生,即哪个分配获胜。例如,该程序

static int x;
static int y;

public static void main(String[] args) {
    Thread t1 = new Thread() {
        @Override public void run() {
            x = 1;
            y = 1;
        }
    };
    Thread t2 = new Thread() {
        @Override public void run() {
            y = 2;
            x = 2;
        }
    };
    t1.start();
    t2.start();
    t1.join();
    t2.join();
    System.out.println(x + "" + y);
}
Run Code Online (Sandbox Code Playgroud)

可能会打印 11、12、21 或 22,即使唯一的数据竞争发生在写入之间,并且 12 无法通过顺序一致的执行获得。