喜欢同步到volatile

St.*_*rio 11 java multithreading synchronization volatile

我已经阅读了这个答案,最后写了以下内容:

使用volatile可以完成的任何事情都可以通过同步来完成,但反之亦然.

目前尚不清楚.JLS 8.3.1.4定义了volatile字段,如下所示:

字段可以声明为volatile,在这种情况下,Java Memory Model可以确保所有线程都看到变量的一致值(第17.4节).

因此,volatile字段与内存可见性有关.另外,据我所提到的答案,读取和写入易失性字段是同步的.

同步反过来保证只有一个线程可以访问同步块.正如我所知,它与内存可见性无关.我错过了什么?

Ben*_*oît 7

实际上,同步也与内存可见性有关,因为JVM 在synchronized块的出口处添加了内存屏障.这确保了一旦第一个线程退出同步块,另一个线程的读取可以保证同步块中线程的写入结果可见.

注意:遵循@PaŭloEbermann的注释,如果另一个线程通过读取内存屏障(例如,通过进入同步块),它们的本地缓存将不会失效,因此它们可能会读取旧值.

同步块的退出是在此doc中发生的:http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility

寻找这些提取物:

只有在读取操作之前发生写入操作时,一个线程的写入结果才能保证对另一个线程的读取可见.

监视器的解锁(同步块或方法退出)发生在同一监视器的每个后续锁定(同步块或方法入口)之前.并且由于之前发生的关系是可传递的,因此在解锁之前线程的所有操作都会发生 - 在任何线程锁定该监视器之后的所有操作之前.