同步 (SW) 顺序与同步顺序 (SO)
Synchronization-with (SW) order vs synchronization order (SO)
此处:http://cs.oswego.edu/pipermail/concurrency-interest/2013-November/011954.html
其中一位对话者说:
In your reasoning, you do not distinguish
between synchronization order (so) and synchronizes-with order (sw)
我也看不出 so 和 sw 之间的区别。有人可以解释一下吗?
EDITED_1:
read(a, !null) (1)
\--po--> vread(a.f, 0)
\---so---> vstore(a.f, 42)
\---po---> store(a) (4)
特别是,我不理解上图:read(a, !null)
(1) 表示操作读取 a
并且它是 not-null 而作为一个动作 (4) store(a)
存储到 a
变量 after (1)。
所以,如果我们有:
read(a) --> store_to_a
read(a)
怎么 return 不为空?
EDITED_2
我不明白:
vstore(A.f, null) --so--> vread(A.f, null) --so--> vstore(A.f, 42)
什么意思vstore(A.f, null)
。我的意思是 A.f
是 int
。那么,为什么作者将null
存储为int呢?与 vread(A.f, null
)
相同
同步顺序是每个单独执行的 属性,它是该执行的 所有 同步操作的顺序。
Synchronizes-with 是部分基于同步顺序的关系(参见 JLS 17.4.4)。
特别是,post 响应假设 sw 与 volatile-read(a.f) 之间存在 sw 关系 和 volatile-write(a.f):没有这样的关系,执行恰好是这两个动作在 同步顺序,但由于没有sw关系,所以不需要引入适当的栅栏(事实上,在某些系统上你可能有read-acquire 后跟一个 store-release,它们不按那个顺序同步),或者,从另一个角度来看,没有 happens-before,所以存在数据竞争,实际行为是任何人的猜测,并且实际上可能 volatile-read(a.f) 读取 0 而不违反 JLS 17 中的任何内容。
编辑 1 的答案
read(a, !null) (1)
\--po--> vread(a.f, 0)
\---so---> vstore(a.f, 42)
\---po---> store(a) (4)
Particullary, I don't undertand the above diagram: read(a, !null)(1)
means that action read a and it is not-null whileas an action (4)
store(a) stored to the a variable after (1).
Action 4 发生在与 Action 1 不同的线程中。因为 f 不是最终字段,而 store(a) 是不是易失性写入,受监视器保护,...没有任何强制订阅线程查看 vstore(a.f, 42) 和 store( a) 的顺序。例如store(a)可以在vstore(a.f, 42).[=15=之前转发到另一个CPU ]
换句话说,图表具有误导性,最好分解为:
Synchronization Order:
vread(a.f, 0) ---so---> vstore(a.f, 42)
Program Order in publishing thread:
vstore(a.f, 42) ---po---> store(a)
Program Order in subscribing thread:
read(a, !null) ---po---> vread(a.f, 0)
仅当程序 无竞争 时才使用单个图表才有意义,这意味着所有执行都需要看起来 sequentially-consistent,这看起来像是简单的线程交错。在没有 DRF-SC(数据竞争自由 - 顺序一致)行为的情况下,事情并没有那么简单。即便如此,我还是会推荐一个带有单独线程的图表,如下所示:
Publishing thread Subscribing thread
read(a, !null)
|
po
|
v
vread(a.f, 0)
/
so
/
v
vstore(a.f, 42)
|
po
|
v
store(a)
happens-before 顺序仅由 intra-thread program-order 的两个线程,并且根本没有 线程间 同步 排序。特别是,vread(a.f, 0) 和 vstore(a.f, 42), 所以存在数据竞争,并不是程序的所有执行都需要看起来是顺序一致.
编辑 2 的答案
What does it mean vstore(A.f, null). I mean A.f is an int. So, why the
author stores null to int? The same with vread(A.f, null)
在这种情况下,作者使用null来表示字段的默认值。这只是符号,不要读太多。
此处:http://cs.oswego.edu/pipermail/concurrency-interest/2013-November/011954.html 其中一位对话者说:
In your reasoning, you do not distinguish between synchronization order (so) and synchronizes-with order (sw)
我也看不出 so 和 sw 之间的区别。有人可以解释一下吗?
EDITED_1:
read(a, !null) (1) \--po--> vread(a.f, 0) \---so---> vstore(a.f, 42) \---po---> store(a) (4)
特别是,我不理解上图:read(a, !null)
(1) 表示操作读取 a
并且它是 not-null 而作为一个动作 (4) store(a)
存储到 a
变量 after (1)。
所以,如果我们有:
read(a) --> store_to_a
read(a)
怎么 return 不为空?
EDITED_2 我不明白:
vstore(A.f, null) --so--> vread(A.f, null) --so--> vstore(A.f, 42)
什么意思vstore(A.f, null)
。我的意思是 A.f
是 int
。那么,为什么作者将null
存储为int呢?与 vread(A.f, null
)
同步顺序是每个单独执行的 属性,它是该执行的 所有 同步操作的顺序。
Synchronizes-with 是部分基于同步顺序的关系(参见 JLS 17.4.4)。
特别是,post 响应假设 sw 与 volatile-read(a.f) 之间存在 sw 关系 和 volatile-write(a.f):没有这样的关系,执行恰好是这两个动作在 同步顺序,但由于没有sw关系,所以不需要引入适当的栅栏(事实上,在某些系统上你可能有read-acquire 后跟一个 store-release,它们不按那个顺序同步),或者,从另一个角度来看,没有 happens-before,所以存在数据竞争,实际行为是任何人的猜测,并且实际上可能 volatile-read(a.f) 读取 0 而不违反 JLS 17 中的任何内容。
编辑 1 的答案
read(a, !null) (1) \--po--> vread(a.f, 0) \---so---> vstore(a.f, 42) \---po---> store(a) (4)
Particullary, I don't undertand the above diagram: read(a, !null)(1) means that action read a and it is not-null whileas an action (4) store(a) stored to the a variable after (1).
Action 4 发生在与 Action 1 不同的线程中。因为 f 不是最终字段,而 store(a) 是不是易失性写入,受监视器保护,...没有任何强制订阅线程查看 vstore(a.f, 42) 和 store( a) 的顺序。例如store(a)可以在vstore(a.f, 42).[=15=之前转发到另一个CPU ]
换句话说,图表具有误导性,最好分解为:
Synchronization Order:
vread(a.f, 0) ---so---> vstore(a.f, 42)
Program Order in publishing thread:
vstore(a.f, 42) ---po---> store(a)
Program Order in subscribing thread:
read(a, !null) ---po---> vread(a.f, 0)
仅当程序 无竞争 时才使用单个图表才有意义,这意味着所有执行都需要看起来 sequentially-consistent,这看起来像是简单的线程交错。在没有 DRF-SC(数据竞争自由 - 顺序一致)行为的情况下,事情并没有那么简单。即便如此,我还是会推荐一个带有单独线程的图表,如下所示:
Publishing thread Subscribing thread
read(a, !null)
|
po
|
v
vread(a.f, 0)
/
so
/
v
vstore(a.f, 42)
|
po
|
v
store(a)
happens-before 顺序仅由 intra-thread program-order 的两个线程,并且根本没有 线程间 同步 排序。特别是,vread(a.f, 0) 和 vstore(a.f, 42), 所以存在数据竞争,并不是程序的所有执行都需要看起来是顺序一致.
编辑 2 的答案
What does it mean vstore(A.f, null). I mean A.f is an int. So, why the author stores null to int? The same with vread(A.f, null)
在这种情况下,作者使用null来表示字段的默认值。这只是符号,不要读太多。