After a lot of research I believe I understand the JMM quite well, certainly well enough to know that when an object is shared between two threads you must synchronize all access on the same monitor. I understand that if multiple active threads access an object concurrently all bets are off as to what they will observe.
However, if an object is deterministically and actually constructed before some other thread which uses it is started (or that thread is even constructed), does the JMM guarantee that the contents of the object seen by the later thread are the same as was configured by the earlier set-up thread.
IOW, is it possible to reference an object for the first time in a thread and observe dirty memory due to, e.g. CPU caching, instead of the real contents of the object? Or does the JMM guarantee that when first obtaining a reference to any given object, the memory it references is coherent?
I ask because there is one specific pattern I use in a number of places which I am still unsure about. Often I have an object which is constructed and configured in a piece-meal fashion and then subsequently used immutably. Because it's configured piece-meal, none of it's members can be final (and I don't want to change these all to a builder pattern unless I have to).
For example, creating an HTTP connection handler, and adding plugin objects to handle specific HTTP requests. The handler is created and configured using mutators, and then installed into a TCP connection processor which uses a thread pool to process connections. Since the connection handler is configured and installed before the connection processor's thread pool is started and never changed once installed into the connection processor I don't use explicit synchronization between the thread which sets everything up and the threads which process connections.
In this specific case, it's probable that the thread configuring is also the same thread which starts the thread pool, and since the thread pool start is synchronized all the threads which run out of it are also synchronized on the same thread pool object, so this might mask any underlying problem (it's not required by my API that the starting thread is the same as the configuring thread).