跨线程的对象可见性

bas*_*kin 2 java concurrency

我对跨线程发布数据和数据更改存在一般性疑问.考虑例如以下类.

public class DataRace {
  static int a = 0;

  public static void main() {
    new MyThread().start();
    a = 1;
  }

  public static class MyThread extends Thread {
    public void run() { 
      // Access a, b.
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

让我们关注main().

明确地

new MyThread().start();
a = 1;
Run Code Online (Sandbox Code Playgroud)

我们在MyThread启动后更改共享变量a,因此可能不是线程安全的发布.

a = 1;
new MyThread().start();
Run Code Online (Sandbox Code Playgroud)

但是这次a中的更改是在新线程中安全发布的,因为Java语言规范(JLS)保证线程A在启动线程B时可见的所有变量对线程B都是可见的,这实际上就像是Thread.start()中的隐式同步.

new MyThread().start();
int b = 1;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,在生成两个线程之后分配新变量时,是否可以保证新变量将安全地发布到所有线程.即如果var b被另一个线程访问,它是否保证看到它的值为1.请注意,我之前没有讨论对b的任何后续修改(当然需要同步),但是第一次完成分配由jvm.

谢谢,

Jon*_*eet 5

我对这一点并不完全确定:

a = 1;
new MyThread().start();
Run Code Online (Sandbox Code Playgroud)

...因为我不确定a在新线程启动之前有什么值可以"刷新"到共享内存.但是,该规范明确地谈到了这一点.在第17.4.4节中,它指出:

启动线程的操作与其启动的线程中的第一个操作同步.

(之后的讨论基本上表明它会没问题.)

我不确定你的最后一个例子(含b)是什么意思.