Singleton mode is one of many design patterns. A singleton class can guarantee that its type will only generate one instance, and that having only one instance is useful in many cases, such as global access and caching expensive resources, but if you use singleton in a multithreaded environment, you might introduce some race condition problems. Since most programming languages do not provide a built-in mechanism for creating a singleton, they need to be implemented by the developer themselves.
1 Overview of single cases
The singleton pattern is used to ensure that a class has only one instance and provides a global access point for the instance. This mode is typically used in conjunction with Factory mode.
General scenarios for single-instance mode:
1) Access shared data, such as configuration data, across the entire application domain.
2) load and cache expensive resources only once, so that you can share access globally and improve performance.
3) Create an application log instance, because normally only one is required.
4) Manage objects in a class that implements the factory pattern.
5) delay in creating a static class, a singleton can be deferred instantiation.
Extension: Spring uses a singleton when creating a bean (by default, Springbean is singleton), and a singleton is used inside Java EE, such as in a service locator. Javase also uses a singleton pattern in the implementation of the runtime class.
However, excessive use of singleton mode means unnecessary resource caches, and the garbage collector cannot reclaim objects and free up valuable memory resources. Of course, this does not make use of the benefits of object creation and inheritance. Using a large number of singleton classes can cause memory and performance problems. And the use of singleton classes is unfriendly to testing.
2 implementation of a single case class
2.1 Simple implementation of a single case class
Because the Singleton has only one instance, you want to control the creation of the object. First, the construction method is privatized. It then provides a way to create an instance, and guarantees that the method is static and returns it if the instance already exists.
Package Com.hzw.singleton;
public class mysingleton{
private static Mysingleton instance;
Private Mysingleton (){}
Public static Mysingleton getinstance () {
if (instance==null) {
Instance = new Mysingleton ();
}
return instance;
}
}
The getinstance () method first determines that the singleton has not been created, if it is not created, otherwise, returns the instance that was created before the call to the getinstance () method. Each subsequent invocation returns an instance of the Mysingleton object that was created earlier, and the code that implements the singleton pattern appears to work correctly, but is actually a bug and incomplete. Because objects are created in a way that is not atomic, they are prone to errors under race conditions. In a multithreaded environment, the consequences of creating multiple singleton instances can result.
2.2 Synchronous singleton ensures thread safety or initializes a singleton class instance when the class loads
In order to solve the race problem above, we need to adopt the locking mechanism where the problem arises. And then release the lock after the instance returns. The lock mechanism is implemented in Java using the Synchronized keyword.
Package Com.hzw.singleton;
public class mysingleton{
private static Mysingleton instance;
Private Mysingleton (){}
Public static synchronized Mysingleton getinstance () {
if (instance==null) {
Instance = new Mysingleton ();
}
return instance;
}
}
Or you can create a singleton instance while loading the class, so that you do not have to synchronize the creation of the singleton instance and create a singleton object when the JVM loads all classes (this occurs before the class calls the GetInstance () method). This is possible because static members and static blocks are executed at class load time.
Package Com.hzw.singleton;
public class mysingleton{
Private Static Final Mysingleton instance = new Mysingleton ();
Private Mysingleton (){}
Public static Mysingleton getinstance () {
return instance;
}
}
Static blocks can also be used, but this results in lazy initialization because static blocks are executed before the method call is constructed.
Package Com.hzw.singleton;
public class mysingleton{
Private Static Mysingleton instance = null;
static{
Instance = new Mysingleton ();
}
Private Mysingleton (){}
Public static Mysingleton getinstance () {
return instance;
}
}
2.3 Using a dual detection lock
Double detection Lock is a popular mechanism for creating singleton, which is more secure than other methods because it checks the creation of a singleton before locking the Singleton class and checks again before the object is created.
Package Com.hzw.singleton;
public class mysingleton{
Private Volatile Mysingleton instance;
Private Mysingleton (){}
Public static Mysingleton getinstance () {
if (instance==null) {
Synchronized (Mysingleton.class) {
if (instance==null) {
Instance = new Mysingleton ();
}
}
}
return instance;
}
}
The getinstance () method checks the private Mysingleton instance member two times before it is created, to see if it is not NULL, and assigns a value to a Mysingleton instance.
2.4 Creating a singleton instance using an enumeration mechanism
None of the above methods are absolutely safe. For example, developers can use the Java Reflection API to change the access permissions of the construction method to public, so that the singleton can be created again.
In Java, the best way to create a singleton is to use the enumeration type introduced in Java5, which is also highly recommended in effective Java. Because enumeration types are inherently singleton, the JVM handles most of the work required to create a singleton. By using enum types, you do not need to work with synchronization object creation (creation of singleton instances) and provide (get created singleton instances), and you can avoid initialization-related issues.
Package Com.hzw.singleton;
public enum mysingletonenum{
INSTANCE;
public void Method1 () {}
public void Method2 () {}
....................
}
In this example, a reference to an instance of a singleton object is obtained in the following way:
Mysingletonenum MSE = mysingletonenum.instance;
Once you have a singleton reference, you can call its method: for example, Mse.method1 ();
A single-instance pattern of Java design patterns