This paper analyzes various implementations of comprehensive singleton pattern in java
- 2021-09-12 01:24:58
- OfStack
1. The idea of singleton pattern
If you want to sort out some knowledge about java concurrency, you don't know where to start. If you think of thread safety to consider in singleton mode, you should start with singleton mode. Write before singleton pattern, here again summary supplement collation 1, singleton pattern of a variety of implementations.
The main idea of singleton pattern is:
Privatize the construction method (declared as private), so that the outside world can't arbitrarily produce new instance objects in new; Declare a private static instance object for external use; Provide a public method to let the outside world get the instance object of this classThis statement seems true, but it also seems inaccurate. In fact, even if the outside world can produce new instance objects at will, as long as we ensure that the objects we use each time are only 1, we can.
2. N implementation of singleton pattern
2.1. Hungry (thread-safe, available)
public class Singleton {
private Singleton() {
}
private static Singleton sSingleton = new Singleton();
public static Singleton getInstance() {
return sSingleton;
}
}
Disadvantages: Class 1 is instantiated when it is loaded, which occupies system resources in advance.
2.2. Constant (thread-safe, available)
public class Singleton {
private Singleton() {
}
public static final Singleton sSingleton = new Singleton();
}
Use the instance object with the
public static final
Modified, does not provide an exposed method to get an instance, and directly passes the
Singleton.sSingleton
Get.
2.3. Lazy (thread is unsafe and concurrent scenarios are unavailable)
public class Singleton {
private Singleton() {
}
private static Singleton sSingleton;
public static Singleton getInstance() {
if (sSingleton == null) {
sSingleton = new Singleton();
}
return sSingleton;
}
}
Disadvantages: The first time the first load response is slightly slow, and the thread is unsafe.
2.4. Synchronized lazy style? (Thread-safe, available, not recommended)
public class Singleton {
private Singleton() {
}
private static Singleton sSingleton;
public synchronized static Singleton getInstance() {
if (sSingleton == null) {
sSingleton = new Singleton();
}
return sSingleton;
}
}
Disadvantages: Slow response on the first load, and every time you call
getInstance
All are synchronized, causing unnecessary synchronization overhead. This mode 1 is generally not recommended.
2.5. Double-checked lock DCL (thread-safe, most scenarios meet the requirements, recommended)
public class Singleton {
private Singleton() {
}
/**
* volatile is since JDK5
*/
private static volatile Singleton sSingleton;
public static Singleton getInstance() {
if (sSingleton == null) {
synchronized (Singleton.class) {
// Is not initialized, the initial instance Variable
if (sSingleton == null) {
sSingleton = new Singleton();
}
}
}
return sSingleton;
}
}
sSingleton = new Singleton () is not a 1 atomic operation. (XXX) Therefore, it must be added
volatile
Keyword modification, which is available after jdk 1.5.
2.6. Static inner classes (thread-safe, recommended)
public class Singleton {
private Singleton () {
}
private static class InnerClassSingleton {
private final static Singleton sSingleton = new Singleton();
}
public static Singleton getInstance() {
return InnerClassSingleton.sSingleton;
}
}
Advantages: Recommended.
2.7. Enumerate singletons (thread-safe, not recommended)
public enum Singleton{
INSTANCE;
// Other methods
public void doSomething(){
...
}
}
Advantages: Enumeration implementation singleton is simple and safe.
Disadvantages: Experienced Android developers will try to avoid using enumerations. According to the official document, it will cost more than twice as much memory as the static constant Enum.
2.8. Alternative Implementation-Using Containers to Implement Singletons
import java.util.HashMap;
import java.util.Map;
public class Singleton {
private static Map<String, Object> objMap = new HashMap<String, Object>();
private Singleton() {
}
public static void registerService(String key, Object instance) {
if (!objMap.containsKey(key)) {
objMap.put(key, instance);
}
}
public static Object getService(String key) {
return objMap.get(key);
}
}
Taking advantage of the non-repeatability of key container HashMap.
Advantages: This implementation enables us to manage various types of singletons, and can obtain operations through the unified 1 interface when using, which reduces the use cost of users, hides the specific implementation for users and reduces the coupling degree. Disadvantages: Without privatization constructor, users can new out new instance objects.
2.9. Prevent reflection from destroying singletons
Many of the previous implementation methods are implemented according to the idea of privatization of construction methods. We know that new objects can still be created by using reflection, so in the reflection scene, the singleton pattern realized by this idea will fail, so how to prevent reflection from destroying the singleton pattern? The principle is to throw an exception when the constructor is called again in the presence of one instance. Let's take the singleton pattern of static inner classes as an example:
public class Singleton {
private static boolean flag = false;
private Singleton(){
synchronized(Singleton.class)
{
if(flag == false)
{
flag = !flag;
}
else
{
throw new RuntimeException(" Singleton pattern is violated! ");
}
}
}
private static class InnerClassSingleton {
private final static Singleton sSingleton = new Singleton();
}
public static Singleton getInstance() {
return InnerClassSingleton.sSingleton;
}
}
2.10. Preventing serialization and deserialization from destroying singletons
By serialization, an object instance can be written to the disk. When it is read back by deserialization, even if the constructor is private, a new instance can still be created by a special way, which is equivalent to calling the constructor of this class. To avoid this problem, we need to add the following method to the code to return an sSingleton object when the readResolve method is executed during deserialization.
private Object readResolve() throws ObjectStreamException {
return sSingleton;
}
3. Conclusion
Is there a way to implement a singleton pattern that is a singleton in any case?
Yes. Is the enumeration singleton mentioned above. Enumeration can be guaranteed to be singleton and thread-safe in any case.
The above is the analysis of java in a comprehensive singleton pattern of a variety of implementation details, more about java singleton pattern implementation of information please pay attention to other related articles on this site!