代码之家  ›  专栏  ›  技术社区  ›  gstackoverflow

顺序一致性挥发性解释

  •  4
  • gstackoverflow  · 技术社区  · 8 年前

    我正在看java jpoint会议的视频。

    Alexey Shipilev 报告:

    enter image description here

    请原谅幻灯片上的非英语内容。实际上作者说变量集不可能

    r1 = 1 (Y)
    r2 = 0 (x)
    r3 = 1 (x)
    r4 = 0 (Y)
    

    有人能澄清为什么根据JMM这个值集是不可能的吗?

    附笔。

    如果我理解Alexey符号正确,则它遵守以下代码:

    public class SequentialConsistency {
        static volatile int x;
        static volatile int y;
    
        public static void main(String[] args) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    x = 1;
                }
            }).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    y = 1;
                }
            }).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("r1=" + x + ", r2=" + y);
                }
            }).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("r3=" + x + ", r4=" + y);
                }
            }).start();
        }
    }
    
    3 回复  |  直到 8 年前
        1
  •  5
  •   Aleksey Shipilev    8 年前

    您可以为此代码构建SC执行的穷举列表,并实现无SC执行生成(1,0,1,0)。

    就模型而言,这很容易引起争论。同步顺序(SO)一致性表示,同步读取应该在SO中看到最后一次同步写入。SO-PO一致性表示SO应与程序顺序一致。

    这允许通过矛盾来勾画证明。假设产生(1,0,1,0)的执行存在。然后,在这些执行中,由于一致性,读取看到的零必须按以下顺序:

    (r2 = x):0 --so--> (x = 1)  [1]
    (r4 = y):0 --so--> (y = 1)  [2]
    

    ...另外两个读操作必须按照写操作的顺序才能看到它们(由于一致性):

    (x = 1) --so--> (r3 = x):1  [3]
    (y = 1) --so--> (r1 = y):1  [4]
    

    ...此外,由于SO-PO的一致性:

    (r1 = y):1 --po--> (r2 = x):0  [5]
    (r3 = x):1 --po--> (r4 = y):0  [6]
    

    这会产生奇怪的传递,因此是循环的:

    (r2 = x):0 --so--> (r3 = x):1 --so--> (r4 = y):0 --so--> (r1 = y):1 --so--> (r2 = x):0
                [1,3]               [6]               [2,4]               [5]
    

    (A --so--> B) (B --so--> A) --这叫做对称。根据定义,总订单也是如此,总订单是 反对称的 这里是对称的。我们已经到了矛盾的地步,因此这种处决是不存在的。Q、 E.D。

        2
  •  2
  •   gstackoverflow    8 年前

    相信我明白了。

    假设我们有4个线程。t1-t4(根据图片从左到右)

    t3 读取 y x 我们看到了结果

    y=1
    x=0
    

    这意味着顺序如下:

    1. t1 y
    2. t3 读取 y
    3. t3 读取 x
    4. 写入 x

    让我们检查一下 t4 读数:

    x=1
    y=0
    

    根据t3的推理,这意味着

    t2 write 发生在之前 t1 write 但这与 t3 因此不可能输出

        3
  •  2
  •   Eugene    4 年前

    volatile 在java中提供 sequential consistency ,这意味着操作已完成 在全球和原子秩序中。如果你写一个字段( x = 1 ),每个人都会看到这样的文字。根据您的示例,如果有 ThreadA x=1 二者都 ThreadB (确实如此 r2 = x )和 ThreadC (确实如此 r3 = x ),将读取 x 成为 1 . 这就是顺序一致性所保证的。

    幻灯片显示 SC (顺序一致)执行: 1, 0, 1, 0 这是不可能的。因为这意味着:

    ThreadA wrote to x value of 1
    ThreadB observed that value to be 1 (via r2 = x)
    ThreadC observed that value to be 0 (via r3 = x)
    

    但在SC世界中,一旦发生写操作(我们知道这是因为 螺纹B 它必须被其他人遵守。但事实并非如此: 螺纹C 看到 x 成为 0 . 因此,这打破了SC。

    禁止 1, 0, 1, 0 虽然 release/acquire