我正在阅读java并发的实践,在“16.1.3 500字或更少的java内存模型”中,它说:
java内存模型是按照动作来指定的,动作包括对变量的读写、监视器的锁定和解锁,以及线程的启动和连接。jmm定义了一个偏序,在程序中的所有操作上调用happens before。为了保证执行动作b的线程能够看到动作a的结果(无论a和b是否出现在不同的线程中),a和b之间必须有一个“发生在”关系。如果没有在两个操作之间排序之前发生的事件,jvm可以随意对它们重新排序。
即使操作只是部分有序的,同步操作也会锁定获取和释放,易变变量的读写也是完全有序的。这使得用“后续”锁获取和易失性变量的读取来描述之前发生的情况变得合理。
关于“偏序”,我发现了这个和这个,但我不太明白“即使动作只是偏序的,同步动作锁定获取和释放,易变变量的读写是完全有序的。”。“同步操作完全有序”是什么意思?
1条答案
按热度按时间u4dcyp6a1#
分析“同步操作是完全有序的”语句:
“同步操作”是一个集合
S
程序操作(动作)的定义我们有关系
R
过度设定S
:它是“发生在”关系。也就是说,给定程序语句a
以及b
,aRb
当且仅当a
以前发生过b
.那么声明所说的,就是“关系”
R
总数超过“s”。“关系
R
一切都结束了S
,表示每两次操作a,b
从集合S
(与a!=b
),或者aRb
,或bRa
. 也就是说a
以前发生过b
,或b
以前发生过a
.如果我们定义集合
S
作为对同一锁对象执行的所有锁获取和锁释放的集合X
; 然后是布景S
完全由“发生在”关系排序:顺其自然a
锁的获得X
由线程执行T1
,和b
由线程执行的锁获取T2
. 那么要么a
以前发生过b
(如果t1首先获得锁。t1需要先释放锁,然后t2才能获得锁);或者b
以前发生过a
(在t2首先获得锁的情况下)。注意:并非所有关系都是完全的。
例如,关系
<=
总数大于实数。也就是说,每一对a,b
对于实数,两种情况a<=b
或者b<=a
. 这里的总订单意味着给定任何两个项目,我们总是可以决定哪一个先到。给定的关系。但是关系
P
:“是的祖先”,并不是所有人类的全部关系。当然,对某些人类来说a,b
这是真的aPb
(a
是…的祖先b
),或bPa
(b
是…的祖先a
). 但对他们大多数人来说,也不是aPb
也不是bPa
是真的;也就是说,我们不能用关系来决定哪一项是“第一项”(按系谱术语)。回到程序语句,在关系之前发生
R
显然是局部的,在所有程序语句的集合上(如“祖先的”示例中):给定不同步的操作a,b
(在没有适当同步的情况下,由不同线程执行的任何操作),也不是aRb
也不是bRa
持有。