intermediateSingleton Pattern

Why does the simple, lazily-initialized Singleton break under concurrency, and how does double-checked locking fix it?

If two threads call the accessor method at nearly the same time, both can read the instance field as null before either one has finished constructing an object, and both proceed to build and assign their own separate instance, violating the entire point of the pattern. Double-checked locking fixes this by checking for null twice: an outer check, unsynchronized, so the common case of the instance already existing skips locking entirely; and an inner check, taken only after acquiring a lock, which prevents two threads that both passed the outer check simultaneously from each constructing a separate object. The instance field also has to be declared volatile, because without it a JVM optimization called instruction reordering could let one thread observe a half-constructed object. A simpler alternative that sidesteps all of this manual locking is an enum-based Singleton, which the JVM guarantees is thread-safe automatically.

Ready to master this question?

Generate a complete walkthrough — background, the full answer in plain language, a working code example explained line by line, a real-world scenario, common mistakes, and how this same question gets asked in different ways.

Sign in to generate a response

Next Step

Continue to Why should a factory method throw an exception for an unrecognized type instead of returning null?← Back to all Low-Level Design & Design Patterns questions