Here’s an idea I just came up with for a safe, efficient way of handling Singleton synchronization issues. It’s basically double-checked locking, but with a twist that involves thread-local storage. In Java/C#/D-style pseudocode, assuming __thread denotes thread-local storage for static variables:
class MySingleton {
__thread static bool isInitialized;
static MySingleton instance;
static MySingleton getInstance() {
if(!isInitialized) {
synchronized {
isInitialized = true;
if(instance is null) {
instance = new MySingleton();
}
}
}
return instance;
}
}
This is guaranteed to only enter the synchronized block once per thread throughout the entire life of the program. From that point forward, we get a simple check of a thread-local bool to see whether we’ve already entered the synchronized block and verified that the object is initialized from this thread.
This appears clean. The actual check and initialization of your instance object is inside a synchronized block and each thread is forced to enter the synchronized block on the first call, you get a clean happens-before edge between threads.
Since isInitialized is thread-local, why are you setting it inside the synchronized block? Also, you should only set isInitalized after constructing your singleton object. This way, if it hasn’t been initialized yet and the constructor throws, this thread will check again the next time it’s called.