Java 同步顺序(SW)与同步顺序(SO)

Java 同步顺序(SW)与同步顺序(SO),java,concurrency,java-memory-model,Java,Concurrency,Java Memory Model,在这里: 一位对话者说: 在你的推理中,你没有区分 在同步顺序(so)和同步顺序(sw)之间 我看不出so和sw之间有什么区别。有人能解释一下吗 已编辑\u 1: 特别是,我不理解上面的图表:read(a,!null)(1)表示操作读取a,并且不为null,而操作(4)store(a)存储在a变量之后 因此,如果我们有: read(a)->store_to_a如何read(a)返回NOTNULL 已编辑_2 我不明白: 它是什么意思vstore(A.f,null)。我的意思是A.f是int。

在这里: 一位对话者说:

在你的推理中,你没有区分 在同步顺序(so)和同步顺序(sw)之间

我看不出so和sw之间有什么区别。有人能解释一下吗


已编辑\u 1:

特别是,我不理解上面的图表:
read(a,!null)
(1)表示操作读取
a
,并且不为null,而操作(4)
store(a)
存储在
a
变量之后

因此,如果我们有:

read(a)->store_to_a
如何
read(a)
返回NOTNULL


已编辑_2 我不明白:


它是什么意思
vstore(A.f,null)
。我的意思是
A.f
int
。那么,为什么作者将
null
存储到int?与
vread(A.f,null
)相同,

同步顺序是每个单独执行的属性,也是该执行上所有同步操作的顺序

与同步是一种部分基于同步顺序的关系(参见JLS 17.4.4)

特别是,此响应的post假设volatile read(a.f)和volatile write(a.f)之间存在sw关系:不存在这样的关系,执行只是碰巧有这两个动作以同步顺序彼此跟随,但由于没有sw关系,不需要引入适当的隔离(事实上,在某些系统上,您可能会先进行读取获取,然后进行存储发布,但不会按照该顺序进行同步),或者,从另一个角度来看,之前没有发生过任何情况,因此存在数据竞争,实际行为是任何人都可以猜测的,实际上,volatile read(a.f)可以在不违反JLS 17中任何内容的情况下读取0

回答编辑1

特别是,我不理解上面的图表:读(a,!null)(1) 表示操作读取a,且在操作(4)时不为空 存储(a)存储到(1)之后的变量a

操作4发生在与操作1不同的线程中。由于f不是最终字段,并且存储(a)不是易失性写,受监视器保护。。。没有任何东西强迫订阅线程按该顺序查看vstore(a.f,42)和存储(a)。e、 g.存储(a)可以在vstore(a.f,42)之前转发到另一个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)
只有在程序没有竞争的情况下才使用单一图表是有意义的,这意味着所有执行都需要顺序一致,这看起来像是线程的简单交错。在没有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) 
before顺序仅由两个线程的线程内程序顺序组成,并且没有线程间程序与顺序同步。特别是,vread(a.f,0)和vstore(a.f,42)之间没有before关系,因此存在数据竞争,并且并非所有程序的执行都需要顺序一致

回答编辑2

vstore(A.f,null)是什么意思。我的意思是A.f是一个整数。那么,为什么 作者将null存储为int?与vread相同(A.f,null)


在本例中,作者使用null表示字段的默认值。这只是符号,不要读太多。

谢谢你的回答。如果可以的话,请阅读我编辑的帖子,试着消除我的疑虑。你太棒了,伙计:)。非常感谢你的解释。“before顺序完全由两个线程的线程内程序顺序组成,并且没有线程间程序与顺序同步。”为什么没有?如果没有线程间的sw关系,那么它以前是如何发生的呢?因此,我的问题的关键是:
op1、op2、op3,vstore、op6
op6
可以使用
op1
op2
vstore
等重新排序,但vstore不能使用
op1、op2、op3、
重新排序,是吗?
   read(a, !null) (1)
      \--po--> vread(a.f, 0)
                    \---so---> vstore(a.f, 42)
                                    \---po---> store(a) (4)
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)
Publishing thread       Subscribing thread

                             read(a, !null)
                                  |
                                  po
                                  |
                                  v
                            vread(a.f, 0)
                          /     
                         so     
                        /       
                       v       
    vstore(a.f, 42)
       |
       po
       |
       v
    store(a)