There’s a big problem with Singletons especially in the C++ language. It’s not obvious how to get them to work with multiple threads. You want one instance in your entire application and how do you handle the race condition when multiple threads ask for the instance at the same time?
Or maybe I should say that while the solution is obvious, it’s often then modified into something that no longer works correctly. There’s a desire to avoid obtaining a lock when we know it’s no longer needed. It probably wouldn’t be so bad if the lock really was needed throughout the application’s lifetime. But because of the way Singletons work, they really only have the potential for a race condition early in the application lifetime. It seems like a waste to continue getting a lock when it’s not needed anymore.
A common “solution” tho this is to use the Double-Checked Locking Design Pattern. This adds very little extra complexity and seems to work perfectly. the only reason it seems to work though is because of the slim chance of hitting the race condition in the first place. It doesn’t actually solve the problem. All it really does is avoid the need to obtain a lock once the initial possible race condition is over.
There are still problems, especially in C++. This episode explains how just checking the instance variable twice doesn’t really solve the problem.