关于缓存的Java final关键字语义
问题描述:
Java final关键字在缓存方面的行为是什么?关于缓存的Java final关键字语义
引自:jsr133-faq
为对象的最终字段中的值在构造函数中进行设置。 假设对象构造“正确”,一旦构建了一个对象 ,分配给构造函数 中最后一个字段的值将对所有其他线程都可见,而不会与 同步。此外,任何其他对象 或由这些最终字段引用的数组的可见值至少与最终字段一样为 。
我不明白它是指当它说as up-to-date as the final fields
:
此外,对于那些最终字段引用的任何其他对象或数组 可见值将至少为最新的最终字段为 。
我的猜测是,例如:
public class CC{
private final Mutable mutable; //final field
private Other other; //non-final field
public CC(Mutable m, Other o){
mutable=m;
other=o;
}
}
当构造CC恢复,除了的mutable
指针值,所有的值上植根于m
,如果存在于本地的处理器高速缓存的对象图,将被刷新到主内存。同时,将其他处理器本地缓存的相应缓存行标记为无效。
是这样吗?装配看起来如何?他们如何实际执行它?
答
是这样吗?
实际保证的是,可以看到使用该构造函数创建的CC
一个实例任何线程保证看到的mutable
参考,也Mutable
对象的字段作为该构造完成时的状态。
它不保证在Mutable
实例的关闭中的所有值的状态都将可见。但是,在构造函数完成之前执行构造函数的线程所做的任何写操作(在闭包中或不在)中将会看到。 (通过“发生之前”分析。)
请注意,行为是按照一个线程保证看到的而不是缓存刷新/无效的方式指定的。后者是实现规范要求的行为的一种方式。可能有其他方法。
它在装配中看起来像什么?
这将是版本/平台/等特定的。如果您想调查硬件的本机代码的外观,有一种方法可以让JIT编译器转储出编译好的代码。
他们如何真正落实呢?
参见上文。
海报询问有关'对象图上的'值'final'的可见性保证。你说这些保证没有扩展到'闭包中的值',但[另一个答案](https://*.com/a/2830895/2402790)表示他们*扩展到对象图上的值。 –
他错了。 (或者正确的...但是这个例子是/假设是不同的。)它取决于哪个线程写入这些值。我的原始陈述没有假设哪个线程(最后一个)写入图形/闭包中的对象。无论如何,我已经澄清了它。 –