Document directory
The Singleton mode is suitable for scenarios where a class has only one instance, such as window manager, print buffer pool, and file system. They are all prototype examples. Typically, objects of different types are accessed by different objects in a software system. Therefore, a global access pointer is required, which is a well-known Singleton mode application. Of course, this is only when you are sure that you no longer need more than one instance.
The purpose of the singleton model is what you are concerned about in the previous section. In Singleton mode, you can:
Make sure that only one instance of a class is created
Provides a global access pointer to the object
Allow multiple instances in the future without affecting the client of the singleton classAlthough the singleton design pattern, as shown in the figure below, is the simplest design pattern, it presents many defects for careless Java developers. This article discusses the singleton model and reveals those defects.
Note: you can download the source code of this article from resources.
Singleton Mode
In the design pattern book, the author describes the Singleton pattern in this way: ensure that a class has only one instance and provides a global access pointer to it.
Class Diagram of Singleton mode is described.
(Figure 1)
Class Diagram of Singleton Mode
As you can see in, this is not the complete Part Of The Singleton mode. In this figure, the single instance class maintains a static reference to the unique Singleton instance and returns a reference to that instance from the static getinstance () method.
Example 1 shows the implementation of a classic Singleton mode.
Example 1. Classic Singleton Mode
public class ClassicSingleton {
private static ClassicSingleton instance = null;
protected ClassicSingleton() {
// Exists only to defeat instantiation.
}
public static ClassicSingleton getInstance() {
if(instance == null) {
instance = new ClassicSingleton();
}
return instance;
}
}
The implementation of the singleton mode in Example 1 is easy to understand. The classicsingleton class maintains a static reference to a single instance and returns the reference from the static method getinstance.
For the classicsingleton class, there are a few topics that interest us. First, classicsingleton uses a well-known lazy Instantiation to create a reference to that Singleton class. As a result, the instance of this Singleton class is not created until the getinstance () method is called for the first time. This technique ensures that instances of the singleton class are created only when necessary. Note that classicsingleton implements a protected constructor, so that the client cannot directly instantiate an instance of the classicsingleton class. However, you will be surprised to find that the following code is completely legal:
public class SingletonInstantiator {
public SingletonInstantiator() {
ClassicSingleton instance = ClassicSingleton.getInstance();
ClassicSingleton anotherInstance =
new ClassicSingleton();
...
}
}
Why can I create an instance without inheriting the classicsingleton class and the classicsingleton class? The answer is that the protected constructor can be called by its subclass and other classes in the same package. Because classicsingleton and singletoninstantiator are in the same package (default package), The singletoninstantiator method can create clasicsingleton instances.
In this case, there are two solutions: First, you can change the classicsingleton constructor to private, so that only the classicsingleton method can call it; however, this also means that classicsingleton cannot have subclasses. Sometimes this is a very satisfactory solution. If so, it is a good idea to declare your Singleton class as final. This is clear and allows the compiler to use some performance optimization options. Another solution is to put your Singleton class in an external package so that classes in other packages (including the default package) cannot instantiate a singleton class.
The third point of interest in classicsingleton is that if a single instance is loaded by a different class loader, there may be instances of multiple Singleton classes. It is assumed that it is not a remote access. For example, some servlet containers use different class loaders for each servlet. In this way, if two servlets access a singleton class, they will all have their own instances.
Fourth, if clasicsingleton implements the java. Io. serializable interface, the instances of this class may be serialized and restored. In any case, if you serialize an object of the singleton class and restore multiple objects, you will have instances of multiple Singleton classes.
The last and most important thing is that the classicsingleton class in Example 1 is not thread-safe. If two threads are called thread 1 and thread 2, classicsingleton is called at the same time. getinstance () method. If thread 1 first enters the if block, and thread 2 controls it, two instances of classicsingleton will be created.
As you have seen in the previous discussion, although the singleton mode is one of the simplest design patterns, implementing it in Java is not as simple as you can imagine. This article will reveal the considerations of the Java specification for the singleton mode, but first let's look at how you can test your Singleton class.