【问题标题】:Java final keyword semantics with respect to cache关于缓存的 Java final 关键字语义
【发布时间】:2016-11-19 09:42:54
【问题描述】:

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

是这样吗?它在装配中是什么样子的?他们实际上是如何实现的?

【问题讨论】:

    标签: java synchronization final


    【解决方案1】:

    是这样吗?

    实际的保证是,任何可以看到使用该构造函数创建的CC 实例的线程都可以保证看到mutable 引用以及Mutable 对象字段的状态,直到构造函数完成。

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

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

    它在装配中是什么样子的?

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

    他们实际上是如何实现的?

    见上文。

    【讨论】:

    • 发帖人询问final 在“对象图上的值”方面的可见性保证。你说这些保证不会扩展到“闭包中的值”,但another answer 说它们确实扩展到对象图上的值。
    • 他错了。 (或者是对的......但例子是/假设不同。)这取决于哪个线程写了这些值。我最初的陈述没有假设哪个线程(最后一个)写入图形/闭包中的对象。反正我已经说清楚了。
    猜你喜欢
    • 2012-12-30
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    • 2018-05-17
    相关资源
    最近更新 更多