To answer the original question as asked: if only one thread is writing, and if you really don't care if some of the reader threads see an old value, then... well even then, you may need to synchronize, or us volatile, or an AtomicBoolean. If you don't do any of these, then there is still a danger that other threads may see the changed value before you think they should be able to (i.e. before the setting thread has completed all the operations it's supposed to). This may seem impossible, but the compiler and JIT are allowed to reorder operations for efficiency if it can be proven programmatically that the reordering will not affect the thread that is executing the code. A simple example:
This seems reasonable. But a JIT may decide to reorder the initialize() method as:
After all, this would clearly make no difference to a single thread. None of the lines of code depend on each other, and it should make no difference if they are reordered. Unless another thread comes along and concurrently tries to read values of isInitialized, x, y, and/or z. That's when problems occur.
Admittedly, in this example, there's no good reason apparent why the JIT might want to make this particular "optimization". But it can happen, with more complex examples. The general point is that with multiple threads, really weird things can happen unless you carefully protect any mutable data that's accessible from more than one thread. [ August 29, 2008: Message edited by: Mike Simmons ]