I feel one reason why the DCL is broken relates to the 3-step process in “k = new Child()”. In c++, new (delete is similarly 2-stepper) is a 3-stepper — allocation + initialization + pointer assignment. JVM is written in c++, so probably same process —
1) allocate — new address for the new born Child
A) address saves to the 4-byte pointer k. Note the actual “store” operation (ie flush to main memory) may be delayed, but ironically not in this case — When you don’t want it delayed, it may; when you want it delayed it may not … Sigh.
B) initialize the memory cells of Child
Now the surprise — Steps A and B could be reordered by compiler. What if address assignment happens before initialization? Creator thread is in the critical section, between Steps A and B, but 2nd thread outside the critical section already sees A’s effect, believing the entire 3-stepper completed!
You may think Steps A and B are very very adjacent, but no no no. In a 128-processor machine with 100 threads on each, a lot of (mostly bad) things can happen when creator thread is pushed to end of the run queue.