是易失读之前发生性写?(Is volatile read happens-before volati

2019-09-04 02:43发布

我试着去了解为什么这个例子是一个正确的同步程序:

a - volatile
Thread1:
x=a
Thread2:
a=5

因为存在冲突的访问(有到写和的读出)所以在每一个顺序的一致性执行必须是之前发生之间访问关系。 假设顺序执行的一项:

1. x=a
2. a=5

1之前发生2,为什么呢?

Answer 1:

否,前一性读(以同步的顺序)相同的变量的易失性写入不一定之前发生挥发性写入。

这意味着他们可以在一个“数据争”,因为他们是“相互矛盾访问了没有通过之前发生关系,有序”。 如果这是真的几乎所有的程序包含数据争:)但是,它可能是一个规范的错误。 挥发性读写不应该被认为是一个数据的比赛。 如果程序中的所有变量是挥发性的,所有执行都是平凡的顺序是一致的。 看到http://cs.oswego.edu/pipermail/concurrency-interest/2012-January/008927.html



Answer 2:

1之前发生2,为什么呢?

我敢肯定不是100%我明白你的问题。

如果你有一个volatile变量a ,一个线程从中读取而另一个写它,这些访问的顺序可以按任意顺序。 这是一个竞争条件 。 什么是JVM和Java内存模型(JMM)保证取决于其操作首先发生。

写可能刚好和读看到更新的价值。 或者写能读以后的事情了。 因此, x可以是任何5或以前的值a

每顺序一致性执行必须是之前发生之间的关系的访问

我不知道,所以让我更具体。 随着“关系之前发生” volatile以前所有的内存写入的手段volatile之前,同一个变量的读变量,保证完成。 但是,这保证不以任何方式解释了两者之间的时序volatile操作,这些操作是受竞争条件。 读者可以保证已经看到了写,但只有当读前写发生。

你可能会认为这是一个相当薄弱的保证,但在线程,其性能急剧通过使用本地CPU缓存,读取字段的值可能来自缓存的内存段,而不是中央记忆改善。 担保是至关重要的,以确保本地线程内存无效和更新,当volatile发生读取,这样线程可以适当地共享数据。

同样,JVM和JMM保证,如果你是从读volatilea ,那么任何写入同一个字段读之前已经发生了 ,会被它看到-写入的值会得到妥善公布,并可见读线程。 然而,这保证不以任何方式决定排序。 这并不是说该写有读之前发生。



Answer 3:

很抱歉,但你不能说正确的JVM将如何优化取决于JVM的“内存模式”的代码。 你必须使用Java的高级工具,用于定义你想要的东西。

如此动荡仅仅意味着将有用于变量没有“线程间高速缓存”。

如果你想有一个严格的命令,你必须使用synchronized块。

http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html



Answer 4:

挥发性和之前发生时才有用当现场的读取硬盘的一些条件。 例如:

volatile int a;
int b =0;
Thread-1:
   b = 5;
   a = 10;
Thread-2
   c = b + a;

在这种情况下不存在之前发生,一个可以是10或0和b可以是5或0,所以作为结果C可以是0,5,10或15。如果的读意味着一些其它条件,那么之前发生,建立了实例:

int b = 0;
volatile int a = 0;
Thread-1:
   b = 5
   a = 10;
Thread 2: 
   if(a == 10){
      c = b + a;
   }

在这种情况下,您将确保C = 15,因为读a==10暗示的写b = 5的之前发生的写a = 10

编辑:更新除了顺序注意到灰色的不一致性



文章来源: Is volatile read happens-before volatile write?