java - “同步动作完全有序”是什么意思?
问题描述
我正在阅读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 变量读取来描述发生之前是明智的。
关于“部分排序”,我已经找到了 this和this,但我不太明白“即使动作只是部分排序,同步操作——锁的获取和释放,以及 volatile 变量的读取和写入——都是完全有序的。” . “同步动作完全有序”是什么意思?
解决方案
分析“同步动作是完全有序的”语句:
- “同步动作”是一组
S
程序操作(动作) - 我们有一个
R
超过集合的关系S
:它是发生前的关系。也就是说,给定程序语句a
和b
,aRb
当且仅当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 先获取锁)。T1
b
T2
a
b
b
a
注意:并非所有关系都是完全的。
例如,该关系<=
是实数的总和。也就是说,对于每一对a,b
实数,要么 要么 是a<=b
真的b<=a
。这里的总顺序意味着给定任何两个项目,我们总是可以决定哪个先到。给定的关系。
但是关系P
:“是的祖先”,并不是所有人类集合的总关系。当然,对于某些人来说, (是 的祖先)或(是 的祖先)a,b
是真的。但对他们中的大多数人来说,既不是也不是真的。也就是说,我们不能使用关系来决定哪个项目“首先”出现(用家谱术语)。aPb
a
b
bPa
b
a
aPb
bPa
回到程序语句,happens-before 关系R
显然是部分的,在所有程序语句的集合上(如“祖先”示例中):给定非同步操作a,b
(由不同线程执行的任何操作,在没有适当的同步),既不aRb
也不bRa
成立。
推荐阅读
- python - Python 项目只采用一开始就初始化的环境变量
- java - 如何在 Spring Security 中使用哈希指定内容安全策略
- javascript - 无法读取未定义的属性“命令”(discord.js)
- c# - 如何在输入系统统一中删除输入绑定
- jenkins - 在 Jenkins 管道内的 shell 脚本中使用 grep 和变量
- javascript - 使用 Jquery 更改引导警报类
- laravel - 有没有更好的方法在 laravel 中编写这个 if 语句
- mysql - uuid上的Mysql密钥分区
- woocommerce - Woocommerce - 在产品卡上显示产品的子类别名称
- deep-learning - 如何在 fastai 中使用测试时间增强进行推理时使用我选择的转换?