在Java中发生在机制之前

在Java中发生在机制之前,java,multithreading,volatile,java-memory-model,Java,Multithreading,Volatile,Java Memory Model,我有一个关于Java中before机制的问题。以下是一个例子: public class MyThread extends Thread { int a = 0; volatile int b = 0; public void run() { try { Thread.sleep(500); } catch (InterruptedException e) {

我有一个关于Java中before机制的问题。以下是一个例子:

public class MyThread extends Thread {

        int a = 0;
        volatile int b = 0;

        public void run() {


            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            read();
        }

        public void write(int a, int b) {
            this.a = a;  
            this.b = b;
        }

        public void read() {
            System.out.println(a + " " + b);
        }


    }
这是以前发生过的一个明显的例子,正如我所知,这是足够安全的
a
将正确地获取新值,因为它位于
b
的初始化之前。但重新订购是否意味着安全得不到保证?我说的是:

public void write(int a, int b) {
    this.b = b;
    this.a = a;//might not work? isn't it?
}
UPD主线程:

public class Main {

    public static void main(String[] args) throws InterruptedException {

        MyThread t = new MyThread();
        t.start();
        t.write(1, 2);


    }
}

b
设置为volatile
并在将值设置为
a
后将
write
设置为
b
,可确保:

  • 如果在
    a
    之前读取
    b
    ,则
  • a
    的值不会早于先前写入
    b
    时的值
  • 也就是说,写入
    b
    和读取
    b
    充当同步点或围栏,这意味着在写入
    b
    之前写入
    a
    的内容将在读取
    b
    之后可读(如果
    a
    被写入多次,则以下写入可能可见,也可能不可见)

    但是,您的代码并不像现在这样安全。在
    read
    中,您有以下表达式:

    a + " " + b
    
    在Java中,。这意味着,
    a
    将在
    b
    之前求值。因此,完全有可能读取
    a
    将看到一个旧值
    a
    ,而读取
    b
    将看到一个新值
    b
    。如果您在
    a
    之前读取了
    b
    ,则发生在关系之前n在
    b
    之间的写入和读取本应包括对
    a
    的写入和对
    a
    的读取。现在,它没有

    至于
    write
    中的重新排序操作,这将明显消除
    b
    的排序保证对
    a
    的操作过度的影响,即使
    read
    先读取
    b
    然后读取
    a

    要将事物形象化,只有
    b
    volatile

    当前的代码不保证对操作的顺序-

    write a                         read a
    write b --> happens before -->  read b
    
    使用给定的读取重新排序
    write
    也不会排序
    a
    -

                                    read a
    write b --> happens before -->  read b
    write a
    
    即使给定的
    读取
    是固定的,
    a
    也不会被
    b
    -

    write b --> happens before -->  read b
    write a                         read a
    
    唯一安全的方法是保持当前的
    写入
    ,并修复
    读取
    -

    write a
    write b --> happens before -->  read b
                                    read a
    

    你能添加包含start()调用的代码吗?我不能完全理解你在这里的要求