2016-11-19 73 views
1

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,如果存在于本地的处理器高速缓存的对象图,将被刷新到主内存。同时,将其他处理器本地缓存的相应缓存行标记为无效。

是这样吗?装配看起来如何?他们如何实际执行它?

回答

2

是这样吗?

实际保证的是,可以看到使用该构造函数创建的CC一个实例任何线程保证看到的mutable参考,也Mutable对象的字段作为该构造完成时的状态。

它不保证在Mutable实例的关闭中的所有值的状态都将可见。但是,在构造函数完成之前执行构造函数的线程所做的任何写操作(在闭包中或不在)中将会看到。 (通过“发生之前”分析。)

请注意,行为是按照一个线程保证看到的而不是缓存刷新/无效的方式指定的。后者是实现规范要求的行为的一种方式。可能有其他方法。

它在装配中看起来像什么?

这将是版本/平台/等特定的。如果您想调查硬件的本机代码的外观,有一种方法可以让JIT编译器转储出编译好的代码。

他们如何真正落实呢?

参见上文。

+0

海报询问有关'对象图上的'值'final'的可见性保证。你说这些保证没有扩展到'闭包中的值',但[另一个答案](https://stackoverflow.com/a/2830895/2402790)表示他们*扩展到对象图上的值。 –

+0

他错了。 (或者正确的...但是这个例子是/假设是不同的。)它取决于哪个线程写入这些值。我的原始陈述没有假设哪个线程(最后一个)写入图形/闭包中的对象。无论如何,我已经澄清了它。 –