Just now, I posted a question on my wechat account: How can I achieve a thread-safe singleton without using synchronized and Lock?

It received hundreds of responses in an instant. The most answered are static inner classes and enumerations. Well, those two things can be done.

The enumeration

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
}  Copy the code

Static inner class

public class Singleton { private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return SingletonHolder.INSTANCE; }}Copy the code

Others answered simply: Hungry. Good. That’s also true.

The hungry

public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; }}Copy the code

The hungry variant

public class Singleton { private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return SingletonHolder.INSTANCE; }}Copy the code

(For more singleton implementations, see: Seven ways to write singleton patterns.)

Q: What is the real rationale behind these ways of implementing singletons?

A: All of the above implementation methods are based on the thread-safety mechanism of the ClassLoader.

Let’s explain why we use the ClassLoader.

We define static member variables to ensure that instance can be instantiated at class initialization. So why is it thread-safe to have instance instantiated at class initialization? Since class initialization is done by the ClassLoader, this takes advantage of the thread-safe mechanism of the ClassLoader.

As for static inner classes, this approach is only slightly different from the two hungrier methods, but a little more elegant. In this way, the Singleton class is loaded and the instance is not necessarily initialized. Because the SingletonHolder class is not actively used, instance instance is instantiated only when the SingletonHolder class is loaded by calling the getInstance method… But the principle is the same as hungry Man.

Finally, enumerations. In fact, if you deserialize enumerations, you’ll see that they also use static final for each item. (See: An in-depth look at Enumerations in Java — Thread safety and serialization of enumerations)

So far, we make it clear that the answer is to use the thread safety mechanism of the ClassLoader. The synchronized keyword is used by the loadClass method of the ClassLoader to load classes that are thread safe. Because of this, this method is synchronous (thread-safe) by default throughout the load process unless overridden. (See in-depth analysis of Java’s ClassLoader mechanism (source level) for more details.)


Hahaha!! So it’s safe to say that everyone’s answers were only half right. Synchronized and lock are not shown, but !!!! is used indirectly

So here’s another question: how do you implement a thread-safe singleton without using synchronized and Lock? How do you implement a thread-safe singleton without using synchronized and Lock? (2)

Copyright Notice


exceptional