首页 > 解决方案 > “同步动作完全有序”是什么意思?

问题描述

我正在阅读Java Concurrency in Practice,在“16.1.3 The Java Memory Model in 500 words or less”中,它说:

Java 内存模型是根据操作指定的,包括对变量的读取和写入、监视器的锁定和解锁以及启动和加入线程。JMM为程序中的所有操作定义了一个称为发生前发生的偏序。为了保证执行动作B的线程可以看到动作A的结果(无论A和B是否发生在不同的线程中),A和B之间必须存在happens-before关系。在没有happens-before排序的情况下在两个操作之间,JVM 可以随意重新排序它们。

即使动作只是部分有序的,同步动作——锁的获取和释放,以及 volatile 变量的读取和写入——都是完全有序的。这使得用“后续”锁定获取和 volatile 变量读取来描述发生之前是明智的。

关于“部分排序”,我已经找到了 thisthis,但我不太明白“即使动作只是部分排序,同步操作——锁的获取和释放,以及 volatile 变量的读取和写入——都是完全有序的。” . “同步动作完全有序”是什么意思?

标签: javamultithreadinghappens-before

解决方案


分析“同步动作是完全有序的”语句:

  • “同步动作”是一组S程序操作(动作)
  • 我们有一个R超过集合的关系S:它是发生前的关系。也就是说,给定程序语句abaRb当且仅当a发生之前b

然后声明说的是“关系在 SR上是完全的”。


“关系R完全超过S”,意味着对于a,b集合S (与a!=b)中的每两个操作,要么aRb,要么bRa。也就是说,要么a发生在之前b,要么发生b在之前a


如果我们将集合定义S为对同一个锁对象执行的所有锁获取和锁释放的集合X;那么这个集合S完全按照happens-before关系排序的:设线程a获取锁,X线程获取锁。然后要么发生在之前(如果 T1 先获取锁。T1 需要先释放锁,然后 T2 才能获取它);或发生在之前(如果 T2 先获取锁)。T1bT2abba


注意:并非所有关系都是完全的。

例如,该关系<=是实数的总和。也就是说,对于每一对a,b实数,要么 要么 是a<=b真的b<=a。这里的总顺序意味着给定任何两个项目,我们总是可以决定哪个先到。给定的关系。

但是关系P:“是的祖先”,并不是所有人类集合的总关系。当然,对于某些人来说, (是 的祖先)或(是 的祖先)a,b是真的。但对他们中的大多数人来说,既不是也不是真的。也就是说,我们不能使用关系来决定哪个项目“首先”出现(用家谱术语)。aPbabbPabaaPbbPa

回到程序语句,happens-before 关系R显然是部分的,在所有程序语句的集合上(如“祖先”示例中):给定非同步操作a,b(由不同线程执行的任何操作,在没有适当的同步),既不aRb也不bRa成立。


推荐阅读