@grumpynerd Hi, Your first assumption is right about new Function(key) may be partially constructed after return of the method except if it is an immutable Object.
Your second assumption is wrong.
this.functionMap = tempMap;
// So here you will either see a null or a fully initialized map.
// Is my understanding right?
return this.functionMap;
now here you are writing and reading a same volatile variable next to next. And you assume that initializeMap will be completed before returns statement.
Your assumption hole True in Roach Motel Model. But its not necessarily true in JMM. as JMM is weaker model than Roach. See answer to the below question Is this a better version of Double Check Locking without volatile and synchronization overhead
Updated from here as it cannot come in comment.
Am sorry your second assumption also hold true.
But keep in mind this.functionMap = tempMap; may in practice behaves like all the statement
have been executed before it and been flush to the memory as it is explained by Doug lea cookbook
http://g.oswego.edu/dl/jmm/cookbook.html this, but this is only a guide on how to implement JMM. For example look the code here
Is this a better version of Double Check Locking without volatile and synchronization overhead
here i tried to use volatile fence as an memory barrier
even if you make the statement
fence = true;
fence = fence;
Now here i am doing volatile read and write, assuming that this will make my object
fully initialized before returning the reference and hence if i again check
that reference to be non-null then i am sure that the object will be fully initialized.
But the above reasoning is flawed because am trying to think in terms of memory barriers
rather than the java happen-before guarantees. What is flawed in my question was that field reference was not volatile therefore any other thread is not reading any volatile reference. If its found field !- null even then it may read wrong values for the other instance fields of FieldType. As there is no guarantees by java when reading non-volatile values.
Therefore never thinks in terms of restricting ordering of statements. Always think
what is guaranteed by JLS/JMM happens before relationship.
for example
int count = 1;
volatile boolean flag = true;
now jls state the above code will run in program order.
i.e count will be 1 first and then flag = true will be executed.
But Not the catch above from jls http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html
It should be noted that the presence of a happens-before relationship
between two actions does not necessarily imply that they
have to take place in that order in an implementation.
If the reordering produces results consistent with a legal execution,
it is not illegal.
For example, the write of a default value to every
field of an object constructed by a thread need not
happen before the beginning of that thread, as long as no
read ever observes that fact.
The above states that count = 1 may be executed after flag = true. if the execution is a legal execution. But our observations would be like that count=1 has been executed first. keyword is
observation. (It may happen here also if suppose compiler finds that flag
not shared among other threads then it might be legal .. this is just hyposthesis)
but now if in another thread executes the below statement then
if(flag == true) {
sysout(count) // count is guaranteed to be 1
// because of volatile guarantees flag will be only true if it has been set by first thread
// and by program order count must have been set before flag has been set to true.
// therefore by program order i am printing count after reading value of a
//volatile variable flag, therefore count must be 1.
}
now if flag would have not been volatile then there is no happen-before relationship
between the two threads. thread 2 very well could read flag == true and count as 0 as there
are no observational guarantees among threads.
In short guarantees are for observations and not how actually each statement executes.
read more about Program Order, Synchronization Order and Happens Before Order and lets share the knowledge :)
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.3