17.5.1 final域的语义
假设O是一个对象,C是O的一个构造器,在这个构造器里面会对final域字段f执行写入操作。当C退出时,会在对象O的final域字段f上执行冻结操作。
注意:
注意: 如果一个构造器调用了另一个构造器并且被调用构造器设置了一个final域,那么冻结操作(freeze)会在被调用的构造器的末尾被执行。
在每一次执行时,读操作都要受到两个偏序的影响:间接引用链 (dereferences)和内存链(memory chain),他们被视为运行的一部分(并且,因此,针对任何特定的执行都是固定的)。这些偏序必须满足下面的约束(它不需要有唯一的解决方案):
1、Dereference Chain: 如果一个线程t没有初始化i对象O,动作a是对O的域字段/元素进行读或写的操作,那么线程t中肯定有一个读操作r可以看到对象O的地址: dereferences(r,a)
-
Memory Chain: 在内存链的顺序上也存在着几个约束:
(1)、如果r是一个能看到写操作w的读操作,那么 r肯定是这种情况:mc(w,r)。
(2)、如果r和a是 dereference(r,a)动作,则一定是这种情况: mc(r,a)。
(3)、如果线程t没有初始化对象O,w是线程t发出的一个写入操作,由w写入对象O的地址,那么 线程t中肯定存在一个可以看到对象O的地址的读操作r, 即: mc(r,w)
给定一个写操作w,冻结操作f,一个动作a(不是对final域的读操作), 对被f冻结的final域的读操作r1以及读操作r2,这样就形成了: hb(w,f), hb(f,a), mc(a,r1), 和 dereferences(r1,r2)。那么在决定哪个值可以被r2看到时,我们认为是:hb(w,r2)。(This happens-before ordering does not transitively close with other happens-before orderings)。
注意: dereferences顺序是自反的(reflexive) ,并且 r1和r2可以是相同的。
针对于final域的读操作,只有那些确实先于final域的读操作之前到来的写入操作,是从final域语义源生出来的。