“部分订购”和发生在关系之前的java

时间:2013-10-01 16:08:53

标签: java concurrency happens-before

我正在阅读以下书籍

  

实践中的Java并发   http://www.informit.com/store/java-concurrency-in-practice-9780321349606

我对关于Happens-before关系的具体解释感到困惑。

它说明了,

  

操作按部分排序命令,名为“发送前”

“偏序”是什么意思?

(书中有一个解释但我不清楚)

2 个答案:

答案 0 :(得分:5)

部分排序意味着并非每对操作都具有happens-before的关系。

实际上,并非每一对操作都具有该关系,这使您可以同时执行操作。

例如,假设您有操作A,B,C& d。

我们可以定义部分排序:A must happen before B and C

然后A和B具有happens-before关系,A和C也是如此。 但是,A和D没有那种关系,所以D可以在A之前,A之后或A执行时执行。

另一方面,如果happens-before是完整的排序,例如A happens-before B happens-before C happens-before D(请注意,在这种情况下,对于每对操作,您知道哪一个发生在另一个之前,因此它是完整的排序),然后操作的执行必须是串行的,并且不可能并发。

答案 1 :(得分:1)

由于您指的是“实践中的Java并发”一书,我想您将参与Java内存模型。

程序员看起来很自然地说CPU按顺序执行程序的语句,因为它们出现在控制流的源代码中。但是优化编译器,CPU架构等几个因素会产生不同的低级行为。但是,这对执行代码的线程不可见。它会表现为好像一切都按顺序发生。

这对多线程不再适用。当在关系存在之前没有发生时,线程可能会观察到另一个线程的不同操作顺序。因此,对于这些操作,不存在指定的排序关系例如。当一个线程执行代码

static Point XY;
…
XY = new Point(3, 4);

另一个线程可能会在初始化该实例的PointXY字段之前观察到x实例存储到y字段中,从而看到(0 ,0)或(3,0)或(0,4)点。

因此,“XY的分配”,“x的分配”和“y的分配”以及阅读这些变量之间的行为之间没有排序关系。

如果我们将变量声明XY更改为volatile,则将Point实例存储到XY并读取该实例引用之间的关系是先发生关系。尽管如此,xy的写入之间没有排序,但现在两个写入都与通过XY读取这两个字段有关系。

这就是部分排序;有些行为有订购关系,有些则没有。