Software Design patterns, also known as Design patterns, are summaries of code Design experiences that have been repeatedly used and known by most people through classification and cataloguing. It describes some recurring problems in the software design process, and the solution to the problem.

That is to say, it is a series of routines to solve specific problems, is the summary of predecessors’ code design experience, has a certain universality, can be used repeatedly.

Its purpose is to improve code reusability, code readability, and code reliability.

So let’s start today with a look at a design pattern that we use especially in our current learning phase – the singleton pattern.

First let’s look at a real-life use of the singleton pattern:

Such as:

Company CEO, department manager and so on all belong to the singleton model

ServletContext and ServletContextConfig in the J2EE standard

ApplicationContext in the Spring Framework application

Connection pooling in the database is also singleton mode

Or the Windows Recycle Bin

The file system in the operating system

Thread pool in multithreading

The driver object for the video card

The printer’s background processing service

Logging object for the application

Connection pooling for the database

Website Counter

A configuration object for a Web application

Dialog boxes in the application

Caches and so on in the system are often designed as singletons.

So why are these situations designed as singletons? What are the implementations of the singleton pattern? What are the advantages and disadvantages of the singleton pattern?

With these questions in mind, let’s take a closer look at the singleton pattern

1. What is a singleton pattern?

Definition of a Singleton pattern: A pattern in which a class has only one instance that the class can create on its own.

For example, in Windows, only one task manager can be opened, which can avoid the waste of memory resources caused by opening multiple task manager Windows, or the inconsistency of display contents of each window and other errors.

2. What are the implementation ways of the singleton pattern?

Common implementation methods are: lazy mode, hungry Han mode, double check lock, static internal class, enumeration and other ways to achieve, then we are followed by a specific one to see their implementation

Slacker Mode:

Public class Singleton {private static Singleton instance = null; private static Singleton instance = null; private static Singleton instance = null; Public static Singleton getInstance(){public static Singleton getInstance(){public static Singleton getInstance(){public static Singleton getInstance(){ If (instance == null){instance = new Singleton(); } return instance; }}

In this code, we are not thinking about thread safety, so we may still have multiple instances, so we need to solve the thread safety problem to get an optimized version of the lazy pattern

Public class Singleton {private static Singleton instance = null; private static Singleton instance = null; private static Singleton instance = null; Private Singleton(){} public static Singleton getInstance(){public static Singleton getInstance(){public static Singleton getInstance(){ If (instance == null){instance = new Singleton(); } return instance; }}

Synchronized is used to ensure the thread-safety of getInstance method. However, this method has great disadvantages, because all threads need to wait in a queue after arriving at this method, so the loss of performance is very large. This process solves the problem of thread-safety rather than efficiency. If we want to solve both the thread safety problem and the efficiency problem, we need to double check the lock mode.

The lazy man pattern allows instantiation to happen when it is needed, which is “lazy loading”. It avoids instantiating instances that might not be needed at load time, but the problem is obvious. We need to work on thread safety issues.

Hungry Man Mode:

/** * @Author HZ * @Version 1.0 */ public class Singleton {private static Singleton instance () {/** * @Author HZ * @Version 1.0 */ public class Singleton {private static Singleton instance () {private static Singleton instance ()  = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return instance; }}

The hungry than idlers, existed at the time of class loading an instance, for example, such as the database connection, idlers is to access the database for the first time I didn’t go to create a connection, and hungry, are you program launched, class loading ok, I already have a connection, you use need not necessarily, so the disadvantage of the hungry also came out: There may be a lot of useless instances.

Then load the timing problem we’ve said, the next step is thread-safe, we didn’t see the synchronized keyword in the code, so this way is how to ensure the safety of the thread, this is the JVM class loading features, the JVM when loading a class is single-threaded, so you can ensure that there is only a single instance

Double check lock:

Public class Singleton {private static Singleton instance = null; private static Singleton instance = null; private static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ synchronized (Singleton.class){ if(instance == null){ instance = new Singleton(); } } } return instance; }}

First, double check lock is also a kind of lazy loading, and better solve the inefficiency in thread-safe, compare the most primitive method of the thread safe (that is, the second code) of the lazy mode, the method to lock the getInstance method, so each call to the method to get the lock, Release the lock, wait, etc… Double-check locks lock parts of the code. The entry method only enters the synchronized code block if the check is null, which is obviously much more efficient.

Static inner classes:

/** * @Author HZ * @Version 1.0 */ public class Singleton {private static class SingletonHolder{private static Singleton instance = new Singleton(); } private Singleton(){} public static Singleton getInstance(){ return SingletonHolder.instance; }}

Lazy mode needs to consider thread safety, so we have to write a lot of code, hungry man mode uses the characteristics of class loading for us to eliminate the consideration of thread safety, then, can not only enjoy the convenience of class loading to ensure thread safety, but also can delay loading way, is static inner class.

The feature of Java static inner classes is that they are not loaded when they are loaded, but are loaded when they are used. The class loading is thread-safe when it is used, which perfectly achieves our expected effect.

Enumeration:

/** * @author Hz * @version 1.0 */ public Enum Singleton {INSTANCE; }

JDK1.5 provides a new data type: enumeration.

The advent of enums provides a more elegant alternative to the large number of static final type variables that existed before. Here, we also use the feature of enumeration to implement the Singleton pattern, and the external invocation is changed from the original Singleton. GetInstance to Singleton.

The implementation of the above singleton pattern has its own advantages, so we need to choose according to our own needs in actual use, and we can summarize the characteristics of the singleton pattern through the above implementation method:

1). The singleton pattern has only one instance object;

2). The singleton object must be created by the singleton class;

3). The singleton class provides a global access point to the singleton.

3. Advantages and disadvantages of the singleton pattern:

Above, we have specifically compared several implementation methods of singleton pattern, then what are the advantages and disadvantages of singleton pattern?

Advantages:

Singleton pattern ensures that there is only one instance in memory, reducing memory overhead.

You can avoid multiple utilizations of resources.

Singleton mode sets up global access points to optimize and share access to resources.

Disadvantages:

Singleton patterns generally have no interfaces and are difficult to extend. If you want to extend it, there is no second way other than to modify the original code, violating the Open Closed Principle.

Singletons are bad for debugging code in concurrent testing. If the code in the singleton does not finish executing during debugging, a new object cannot be emulated.

The functional code of the singleton pattern is usually written in a single class, and it is easy to violate the Single Responsibility Principle if the functional design is not reasonable.

4. Application scenarios of singleton pattern:

In the case of Java, the singleton pattern guarantees that only a single instance exists within a JVM.

The application scenarios of singleton pattern mainly include the following aspects:

For classes that need to be created frequently, using singletons can reduce memory stress on the system and reduce GC.

When a class requires only one object to be generated, such as the monitor of a class, the ID number of each person, etc.

Some classes take a lot of time to create or instantiate, and are often used.

When a class needs to be instantiated frequently and the object created is destroyed frequently, such as multithreaded thread pool, network connection pool, etc.

Objects that frequently access a database or file.

For some operations at the control hardware level, or operations that should have a single control logic in the system, if there are multiple instances, the system will be completely messed up.

When an object needs to be shared. Since the singleton pattern allows only one object to be created, sharing that object saves memory and speeds up object access. For example, the configuration object in the Web, the connection pool of the database, etc.

5. Conclusion:

In the various design methods of the singleton pattern, we use the features of internal static classes, use the features of enumeration, so the foundation is very important, the singleton pattern is one of the design patterns, and the design pattern is actually a further wrapper for the language features are not good side. By absorbing the basics and thinking more about work and study, design patterns will naturally be understood.