Hmm, my mental model is "Java does not guarantee that another thread would ever see a value set to non-volatile non-final variable" (unless we have some synchronized blocks in place). There is no happens-before relationship with no volatile modifier.
In practice, as long as JIT does not interfere all threads see values from each other almost immediately and there would be "some" synchronized block that would sync threads' memory. And usually there is a VM optimization that waits for all fields to be initialized on an object if there is at least one final field present. So in almost all cases omitting volatile and final does not break anything in real-world applications.
|