When we are writing code that sometimes requires some object to be created, and sometimes not, we can save some execution time by only creating this object when it is needed. This process-lazy initialization is explained in Chapter 10, Singleton, Dependency Injection, Lazy Initialization, and Object Pool. That chapter, however, only covered single-threaded applications.
To do lazy initialization properly in a multithreaded world, we need locking. And to do it correctly and fast, we need a double-checked locking pattern. This pattern can speed up any lock that is only acquired if some condition is met. It is also called test, lock, and test again.