While reading Java language specifications, I found this excerpt about finite fields:
The usage model for final fields is simple: set the final fields for an object in this object constructor; and do not write a link to an object that is being built in a place where the thread can see it until the constructor of the object is completed. If this is, then when the object is being viewed by another thread, this thread will always see a correctly constructed version of this object's finite fields. He will also see the versions of any object or array referenced by those trailing fields, which are at least the last since trailing fields .
Link: https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.5
My question is, does version mean updates? Does this mean that after the construction is completed, non-final / non-volatile fields of the object referenced by the final field will also be read from the main memory (and not the local cache)?
Example
So, let's say thread #1 creates objectB and sets one of its non-financial / non-volatile fields.
Then thread #2 sets the same field to something else, creates another objectA with the final field specified as objectB , then puts objectA somewhere where thread #1 can get it.
thread #1 then gets objectA and sees its final field as objectB . Is it possible for thread #1 not to see the changes to objectB made by thread #2 ?
Or here is what code shows what I mean:
public class Test { private static final ConcurrentLinkedQueue<A> myAs = new ConcurrentLinkedQueue<>(); private static long timer = System.nanoTime() + 3000000000L;
It seems that the code is reading the updated values, but I'm not sure if this is just by accident.
java multithreading concurrency thread-safety volatile
Brandon D. McKay
source share