Java 关于缓存的最终关键字语义

Java final keyword semantics with respect to cache

Java final 关键字在缓存方面的行为是什么?

引用自:jsr133-faq

The values for an object's final fields are set in its constructor. Assuming the object is constructed "correctly", once an object is constructed, the values assigned to the final fields in the constructor will be visible to all other threads without synchronization. In addition, the visible values for any other object or array referenced by those final fields will be at least as up-to-date as the final fields.

我不明白as up-to-date as the final fields指的是什么。:

In addition, the visible values for any other object or array referenced by those final fields will be at least 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;
    }
}

当构造函数CCreturns时,除了mutable的指针值外,以m为根的对象图上的所有值,如果存在于本地处理器缓存中,将被刷新到主内存。并同时将其他处理器本地缓存对应的缓存行标记为Invalid。

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

Is that the case?

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

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

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

What does it look like in assembly?

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

  • How to see JIT-compiled code in JVM?

How do they actually implement it?

见上文。