我试图理解Java Memory Model,但我在操作方面遇到了一些麻烦。我将操作的定义理解为< t,k,v,u >,但我不太了解程序如何被分解为操作,以及这些操作的抽象程度如何。
我的第一个假设是行动是原子的。 var1 = var2
会分为两个行为 - 读取var2
和写入var1
,但示例here表明var1 = var2
本身就是一个行为。因此,每个操作都对应于源代码中的一个语句。
这如何与if语句一起使用?例如,如果我们有if(r1 == r2 && r3 == r4) { ... }
,整个陈述是一个动作,还是分成多个动作(如果是,那么相应的动作如何保持连接'作为if语句)?
答案 0 :(得分:3)
动作在JLS 17.4.2中定义,特别关注"线程间动作:"
线程间操作是由一个线程执行的操作,可以被另一个线程检测到或直接受其影响。 ...此规范仅涉及线程间操作。
这些操作的完整列表位于链接处(并不值得在此完全复制),但它包括对变量的读写。
var1 = var2
的问题取决于var1
和var2
是什么。如果他们是某个类的两个字段,那么这些是两个单独的操作(读取var2
并写入var
)。如果它们中的任何一个是局部变量,那么它的状态属于方法的堆栈帧,它本身就是线程本地的,因此不是线程间的动作。
例如,如果var2
是一个字段而var1
是一个局部变量,那么唯一的线程间操作就是读取var2
- 将该值写入局部变量不是一个线程间动作,因为它只能被本地堆栈帧所属的线程观察到。
类似地,if (r1 == r2 && r3 == r4)
最多可以有4个动作:读取四个变量(如果它们是字段)。 ==
和&&
操作的结果是线程本地的,因此不会被视为线程间操作。