du369
du369

Reputation: 821

Java final keyword semantics with respect to cache

What is the behavior of Java final keyword with respect of caches?

quote from: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.

I don't understand what it refers to when it says 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.

My guess is, for example:

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;
    }
}

When the constructor CC returns, besides the pointer value of mutable, all values on the object graph rooted at m, if exist in the local processor cache, will be flushed to main memory. And at the same time, mark the corresponding cache lines of other processors' local caches as Invalid.

Is that the case? What does it look like in assembly? How do they actually implement it?

Upvotes: 1

Views: 621

Answers (1)

Stephen C
Stephen C

Reputation: 719346

Is that the case?

The actual guarantee is that any thread that can see an instance of CC created using that constructor is guaranteed to see the mutable reference and also the state of the Mutable object's fields as of the time that the constructor completed.

It does not guarantee that the state of all values in the closure of the Mutable instance will be visible. However, any writes (in the closure or not) made by the thread that executed the constructor prior to the constructor completing will be visible. (By "happens-before" analysis.)

Note that the behavior is specified in terms what one thread is guaranteed to see, not in terms of cache flushing / invalidation. The latter is a way of implementing the behavior that the specification requires. There may be other ways.

What does it look like in assembly?

That will be version / platform / etc specific. There is a way to get the JIT compiler to dump out the compiled code, if you want to investigate what the native code looks like for your hardware.

How do they actually implement it?

See above.

Upvotes: 2

Related Questions