Double-checked locking is the practice of checking a lazy-initialized object’s state both before and after a synchronized
block is
entered to determine whether to initialize the object. In early JVM versions, synchronizing entire methods was not performant, which sometimes caused
this practice to be used in its place.
Apart from float
and int
types, this practice does not work reliably in a platform-independent manner without additional
synchronization of mutable instances. Using double-checked locking for the lazy initialization of any other type of primitive or mutable object risks
a second thread using an uninitialized or partially initialized member while the first thread is still creating it. The results can be unexpected,
potentially even causing the application to crash.